mirror of https://github.com/acidanthera/audk.git
1. Add NULL QH to set as QH header;
2. Do ping for high speed OUT pipe; 3. Bug fix for QTD size detection; 4. Bug fix for short package detection; 5. Bug fix get next QTD in ExcutionTransfer; 6. BOT module modify to follow spec; 7. Massstorage error hanling enhancement git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2321 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
01bf334d2c
commit
4d1fe68e1c
|
@ -22,7 +22,8 @@ Revision History
|
|||
|
||||
#include "Ehci.h"
|
||||
|
||||
void
|
||||
|
||||
VOID
|
||||
DumpEHCIPortsStatus (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
)
|
||||
|
@ -47,6 +48,8 @@ DumpEHCIPortsStatus (
|
|||
);
|
||||
DEBUG((gEHCDebugLevel, "Port[%d] = 0x%x\n", Index, Value));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Revision History
|
|||
#include "Ehci.h"
|
||||
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCDebugLevel = EFI_D_INFO;
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCDebugLevel = EFI_D_ERROR;
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCErrorLevel = EFI_D_ERROR;
|
||||
|
||||
|
||||
|
@ -353,6 +353,7 @@ EhciDriverBindingStart (
|
|||
UINT8 MaxSpeed;
|
||||
UINT8 PortNumber;
|
||||
UINT8 Is64BitCapable;
|
||||
UINT64 Supports;
|
||||
|
||||
//
|
||||
// Open the PciIo Protocol
|
||||
|
@ -375,10 +376,19 @@ EhciDriverBindingStart (
|
|||
//
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
EfiPciIoAttributeOperationSupported,
|
||||
0,
|
||||
&Supports
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
Supports,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto close_pciio_protocol;
|
||||
|
@ -483,13 +493,18 @@ EhciDriverBindingStart (
|
|||
goto deinit_perodic_frame_list;
|
||||
}
|
||||
|
||||
Status = CreateNULLQH (HcDev);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto deinit_perodic_frame_list;
|
||||
}
|
||||
//
|
||||
// Create AsyncRequest Polling Timer
|
||||
//
|
||||
Status = CreatePollingTimer (HcDev, (EFI_EVENT_NOTIFY) AsyncRequestMoniter);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto deinit_memory_management;
|
||||
goto deinit_null_qh;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -538,7 +553,8 @@ EhciDriverBindingStart (
|
|||
//
|
||||
deinit_timer:
|
||||
DestoryPollingTimer (HcDev);
|
||||
deinit_memory_management:
|
||||
deinit_null_qh:
|
||||
DestroyNULLQH(HcDev);
|
||||
DeinitialMemoryManagement (HcDev);
|
||||
deinit_perodic_frame_list:
|
||||
DeinitialPeriodicFrameList (HcDev);
|
||||
|
@ -593,6 +609,7 @@ EhciDriverBindingStop (
|
|||
EFI_STATUS Status;
|
||||
EFI_USB2_HC_PROTOCOL *Usb2Hc;
|
||||
USB2_HC_DEV *HcDev;
|
||||
UINT64 Supports;
|
||||
|
||||
//
|
||||
// Test whether the Controller handler passed in is a valid
|
||||
|
@ -658,6 +675,11 @@ EhciDriverBindingStop (
|
|||
//
|
||||
DeinitialPeriodicFrameList (HcDev);
|
||||
|
||||
//
|
||||
// Destroy NULLQH
|
||||
//
|
||||
DestroyNULLQH (HcDev);
|
||||
|
||||
//
|
||||
// Deinit Ehci pool memory management
|
||||
//
|
||||
|
@ -673,10 +695,19 @@ EhciDriverBindingStop (
|
|||
//
|
||||
Status = HcDev->PciIo->Attributes (
|
||||
HcDev->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
EfiPciIoAttributeOperationSupported,
|
||||
0,
|
||||
&Supports
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||
Status = HcDev->PciIo->Attributes (
|
||||
HcDev->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
Supports,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
|
|
|
@ -36,6 +36,9 @@ extern UINTN gEHCErrorLevel;
|
|||
#define STALL_1_MILLI_SECOND 1000 * STALL_1_MACRO_SECOND
|
||||
#define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND
|
||||
|
||||
#define MEM_UNIT_SIZE 128
|
||||
|
||||
|
||||
#define SETUP_PACKET_PID_CODE 0x02
|
||||
#define INPUT_PACKET_PID_CODE 0x01
|
||||
#define OUTPUT_PACKET_PID_CODE 0x0
|
||||
|
@ -54,7 +57,7 @@ extern UINTN gEHCErrorLevel;
|
|||
|
||||
#define USB_BAR_INDEX 0 /* how many bytes away from USB_BASE to 0x10 */
|
||||
|
||||
#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1
|
||||
#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16
|
||||
|
||||
#define EHCI_MIN_PACKET_SIZE 8
|
||||
#define EHCI_MAX_PACKET_SIZE 1024
|
||||
|
@ -64,7 +67,7 @@ extern UINTN gEHCErrorLevel;
|
|||
#define EHCI_MAX_QTD_CAPACITY (EFI_PAGE_SIZE * 5)
|
||||
|
||||
#define NAK_COUNT_RELOAD 3
|
||||
#define QTD_ERROR_COUNTER 1
|
||||
#define QTD_ERROR_COUNTER 3
|
||||
#define HIGH_BANDWIDTH_PIPE_MULTIPLIER 1
|
||||
|
||||
#define QTD_STATUS_ACTIVE 0x80
|
||||
|
@ -210,6 +213,9 @@ typedef struct {
|
|||
UINT8 BaseCode;
|
||||
} USB_CLASSC;
|
||||
|
||||
//
|
||||
//32 Bytes Aligned
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 NextQtdTerminate : 1;
|
||||
UINT32 Rsvd1 : 4;
|
||||
|
@ -242,13 +248,12 @@ typedef struct {
|
|||
UINT32 Rsvd6 : 12;
|
||||
UINT32 BufferPointer4 : 20;
|
||||
|
||||
UINT32 ExtBufferPointer0;
|
||||
UINT32 ExtBufferPointer1;
|
||||
UINT32 ExtBufferPointer2;
|
||||
UINT32 ExtBufferPointer3;
|
||||
UINT32 ExtBufferPointer4;
|
||||
UINT32 PAD[5];
|
||||
} EHCI_QTD_HW;
|
||||
|
||||
//
|
||||
//32 Bytes Aligned
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 QhTerminate : 1;
|
||||
UINT32 SelectType : 2;
|
||||
|
@ -307,11 +312,7 @@ typedef struct {
|
|||
UINT32 Rsvd6 : 12;
|
||||
UINT32 BufferPointer4 : 20;
|
||||
|
||||
UINT32 ExtBufferPointer0;
|
||||
UINT32 ExtBufferPointer1;
|
||||
UINT32 ExtBufferPointer2;
|
||||
UINT32 ExtBufferPointer3;
|
||||
UINT32 ExtBufferPointer4;
|
||||
UINT32 Pad[5];
|
||||
} EHCI_QH_HW;
|
||||
|
||||
typedef struct {
|
||||
|
@ -326,7 +327,9 @@ typedef struct {
|
|||
typedef struct _EHCI_QTD_ENTITY EHCI_QTD_ENTITY;
|
||||
typedef struct _EHCI_QH_ENTITY EHCI_QH_ENTITY;
|
||||
typedef struct _EHCI_ASYNC_REQUEST EHCI_ASYNC_REQUEST;
|
||||
|
||||
//
|
||||
//Aligan On 32 Bytes
|
||||
//
|
||||
struct _EHCI_QTD_ENTITY {
|
||||
EHCI_QTD_HW Qtd;
|
||||
UINT32 TotalBytes;
|
||||
|
@ -337,7 +340,9 @@ struct _EHCI_QTD_ENTITY {
|
|||
EHCI_QTD_ENTITY *AltNext;
|
||||
EHCI_QH_ENTITY *SelfQh;
|
||||
};
|
||||
|
||||
//
|
||||
//Aligan On 32 Bytes
|
||||
//
|
||||
struct _EHCI_QH_ENTITY {
|
||||
EHCI_QH_HW Qh;
|
||||
EHCI_QH_ENTITY *Next;
|
||||
|
@ -390,8 +395,9 @@ typedef struct _USB2_HC_DEV {
|
|||
EFI_EVENT AsyncRequestEvent;
|
||||
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
||||
MEMORY_MANAGE_HEADER *MemoryHeader;
|
||||
UINT8 Is64BitCapable;
|
||||
UINT8 Is64BitCapable;
|
||||
UINT32 High32BitAddr;
|
||||
EHCI_QH_ENTITY *NULLQH;
|
||||
UINT32 UsbCapabilityLen;
|
||||
UINT16 DeviceSpeed[16];
|
||||
} USB2_HC_DEV;
|
||||
|
@ -2173,28 +2179,7 @@ Returns:
|
|||
--*/
|
||||
;
|
||||
|
||||
UINTN
|
||||
GetNumberOfTransaction (
|
||||
IN UINTN SizeOfData,
|
||||
IN UINTN SizeOfTransaction
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Number of Transactions in one Qtd
|
||||
|
||||
Arguments:
|
||||
|
||||
SizeOfData - Size of one Qtd
|
||||
SizeOfTransaction - Size of one Transaction
|
||||
|
||||
Returns:
|
||||
|
||||
Number of Transactions in this Qtd
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
UINTN
|
||||
GetCapacityOfQtd (
|
||||
|
@ -2682,6 +2667,32 @@ Returns:
|
|||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CreateNULLQH (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Create the NULL QH to make it as the Async QH header
|
||||
|
||||
Arguments:
|
||||
|
||||
HcDev - USB2_HC_DEV
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Success
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
DestroyNULLQH (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
);
|
||||
|
||||
VOID
|
||||
ClearLegacySupport (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
|
@ -2692,8 +2703,11 @@ HostReset (
|
|||
IN USB2_HC_DEV *HcDev
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
DumpEHCIPortsStatus (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -73,7 +73,7 @@ Returns:
|
|||
//
|
||||
// each bit in Bit Array will manage 32 bytes memory in memory block
|
||||
//
|
||||
(*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;
|
||||
(*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / MEM_UNIT_SIZE) / 8;
|
||||
|
||||
//
|
||||
// Allocate memory for BitArray
|
||||
|
@ -244,8 +244,8 @@ Returns:
|
|||
//
|
||||
// allocate unit is 32 bytes (align on 32 byte)
|
||||
//
|
||||
if (AllocSize & 0x1F) {
|
||||
RealAllocSize = (AllocSize / 32 + 1) * 32;
|
||||
if (AllocSize & (MEM_UNIT_SIZE - 1)) {
|
||||
RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
|
||||
} else {
|
||||
RealAllocSize = AllocSize;
|
||||
}
|
||||
|
@ -262,17 +262,21 @@ Returns:
|
|||
Status = AllocMemInMemoryBlock (
|
||||
TempHeaderPtr,
|
||||
(VOID **) Pool,
|
||||
RealAllocSize / 32
|
||||
RealAllocSize / MEM_UNIT_SIZE
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
ZeroMem (*Pool, AllocSize);
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
ZeroMem (*Pool, AllocSize);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// There is no enough memory,
|
||||
// Create a new Memory Block
|
||||
|
@ -303,13 +307,15 @@ Returns:
|
|||
Status = AllocMemInMemoryBlock (
|
||||
NewMemoryHeader,
|
||||
(VOID **) Pool,
|
||||
RealAllocSize / 32
|
||||
RealAllocSize / MEM_UNIT_SIZE
|
||||
);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
ZeroMem (*Pool, AllocSize);
|
||||
}
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -354,8 +360,8 @@ Returns:
|
|||
//
|
||||
// allocate unit is 32 byte (align on 32 byte)
|
||||
//
|
||||
if (AllocSize & 0x1F) {
|
||||
RealAllocSize = (AllocSize / 32 + 1) * 32;
|
||||
if (AllocSize & (MEM_UNIT_SIZE - 1)) {
|
||||
RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
|
||||
} else {
|
||||
RealAllocSize = AllocSize;
|
||||
}
|
||||
|
@ -373,14 +379,16 @@ Returns:
|
|||
// Pool is in the Memory Block area,
|
||||
// find the start byte and bit in the bit array
|
||||
//
|
||||
StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;
|
||||
StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);
|
||||
StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) / 8;
|
||||
StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) & 0x7);
|
||||
|
||||
//
|
||||
// reset associated bits in bit arry
|
||||
//
|
||||
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {
|
||||
TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ (bit (Index2)));
|
||||
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / MEM_UNIT_SIZE); Count++) {
|
||||
ASSERT ((TempHeaderPtr->BitArrayPtr[Index] & bit (Index2) )== bit (Index2));
|
||||
|
||||
TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));
|
||||
Index2++;
|
||||
if (Index2 == 8) {
|
||||
Index += 1;
|
||||
|
@ -508,7 +516,7 @@ Returns:
|
|||
//
|
||||
// right shift the byte
|
||||
//
|
||||
ByteValue /= 2;
|
||||
ByteValue = ByteValue >> 1;
|
||||
|
||||
if (BitValue == 0) {
|
||||
//
|
||||
|
@ -595,7 +603,8 @@ Returns:
|
|||
//
|
||||
for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
|
||||
|
||||
MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8) (MemoryHeader->BitArrayPtr[TempBytePos] | (bit (Index)));
|
||||
ASSERT ((MemoryHeader->BitArrayPtr[TempBytePos] & bit (Index) )== 0);
|
||||
MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);
|
||||
Index++;
|
||||
if (Index == 8) {
|
||||
TempBytePos += 1;
|
||||
|
@ -603,7 +612,7 @@ Returns:
|
|||
}
|
||||
}
|
||||
|
||||
*Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;
|
||||
*Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * MEM_UNIT_SIZE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -675,6 +684,7 @@ Returns:
|
|||
// Link the before and after
|
||||
//
|
||||
TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
|
||||
NeedFreeMemoryHeader->Next = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,6 +198,8 @@ Returns:
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
ClearLegacySupport (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
|
|
|
@ -21,6 +21,155 @@ Revision History
|
|||
|
||||
#include "Ehci.h"
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
SetAndWaitDoorBell (
|
||||
IN USB2_HC_DEV *HcDev,
|
||||
IN UINTN Timeout
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Set DoorBell and wait it to complete
|
||||
|
||||
Arguments:
|
||||
|
||||
HcDev - USB2_HC_DEV
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Success
|
||||
EFI_DEVICE_ERROR Fail
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Data;
|
||||
UINTN Delay;
|
||||
|
||||
Status = ReadEhcOperationalReg (
|
||||
HcDev,
|
||||
USBCMD,
|
||||
&Data
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Data |= USBCMD_IAAD;
|
||||
Status = WriteEhcOperationalReg (
|
||||
HcDev,
|
||||
USBCMD,
|
||||
Data
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Timeout is in US unit
|
||||
//
|
||||
Delay = (Timeout / 50) + 1;
|
||||
do {
|
||||
Status = ReadEhcOperationalReg (
|
||||
HcDev,
|
||||
USBSTS,
|
||||
&Data
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((Data & USBSTS_IAA) == USBSTS_IAA) {
|
||||
break;
|
||||
}
|
||||
|
||||
gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
|
||||
|
||||
} while (Delay--);
|
||||
|
||||
Data = Data & 0xFFFFFFC0;
|
||||
Data |= USBSTS_IAA;
|
||||
Status = WriteEhcOperationalReg (
|
||||
HcDev,
|
||||
USBSTS,
|
||||
Data
|
||||
);
|
||||
|
||||
exit:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
CreateNULLQH (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Create the NULL QH to make it as the Async QH header
|
||||
|
||||
Arguments:
|
||||
|
||||
HcDev - USB2_HC_DEV
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Success
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EHCI_QH_ENTITY *NULLQhPtr;
|
||||
//
|
||||
// Allocate memory for Qh structure
|
||||
//
|
||||
Status = EhciAllocatePool (
|
||||
HcDev,
|
||||
(UINT8 **) &NULLQhPtr,
|
||||
sizeof (EHCI_QH_ENTITY)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
NULLQhPtr->Qh.Status = QTD_STATUS_HALTED;
|
||||
NULLQhPtr->Qh.HeadReclamationFlag = 1;
|
||||
NULLQhPtr->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(NULLQhPtr->Qh) >> 5));
|
||||
NULLQhPtr->Qh.SelectType = QH_SELECT_TYPE;
|
||||
NULLQhPtr->Qh.NextQtdTerminate = 1;
|
||||
|
||||
NULLQhPtr->Next = NULLQhPtr;
|
||||
NULLQhPtr->Prev = NULLQhPtr;
|
||||
|
||||
HcDev->NULLQH = NULLQhPtr;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
DestroyNULLQH (
|
||||
IN USB2_HC_DEV *HcDev
|
||||
)
|
||||
{
|
||||
|
||||
if (HcDev->NULLQH != NULL) {
|
||||
EhciFreePool (HcDev, (UINT8 *)HcDev->NULLQH, sizeof (EHCI_QH_ENTITY));
|
||||
HcDev->NULLQH = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
InitialPeriodicFrameList (
|
||||
IN USB2_HC_DEV *HcDev,
|
||||
|
@ -337,10 +486,6 @@ Returns:
|
|||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto exit;
|
||||
}
|
||||
//
|
||||
// Init fields in Qh
|
||||
//
|
||||
ZeroMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY));
|
||||
|
||||
//
|
||||
// Software field
|
||||
|
@ -359,8 +504,8 @@ Returns:
|
|||
QhHwPtr->SelectType = 0;
|
||||
QhHwPtr->MaxPacketLen = (UINT32) MaxPacketLen;
|
||||
QhHwPtr->EndpointSpeed = (DeviceSpeed & 0x3);
|
||||
QhHwPtr->EndpointNum = (Endpoint & 0x0f);
|
||||
QhHwPtr->DeviceAddr = (DeviceAddr & 0x7f);
|
||||
QhHwPtr->EndpointNum = (Endpoint & 0x0F);
|
||||
QhHwPtr->DeviceAddr = (DeviceAddr & 0x7F);
|
||||
QhHwPtr->Multiplier = HIGH_BANDWIDTH_PIPE_MULTIPLIER;
|
||||
QhHwPtr->Rsvd1 = 0;
|
||||
QhHwPtr->Rsvd2 = 0;
|
||||
|
@ -467,7 +612,9 @@ Returns:
|
|||
(*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
|
||||
(*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
|
||||
(*QhPtrPtr)->Qh.QhTerminate = FALSE;
|
||||
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
|
||||
if (EFI_USB_SPEED_HIGH != DeviceSpeed) {
|
||||
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
|
||||
}
|
||||
(*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
|
||||
if (NULL != Translator) {
|
||||
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
|
||||
|
@ -696,11 +843,6 @@ Returns:
|
|||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto exit;
|
||||
}
|
||||
//
|
||||
// Init fields in Qtd
|
||||
//
|
||||
|
||||
ZeroMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY));
|
||||
|
||||
//
|
||||
// Software field
|
||||
|
@ -961,7 +1103,6 @@ Returns:
|
|||
UINTN CapacityOfQtd;
|
||||
UINTN SizePerQtd;
|
||||
UINTN DataCount;
|
||||
UINTN Xnum;
|
||||
|
||||
QtdPtr = NULL;
|
||||
PreQtdPtr = NULL;
|
||||
|
@ -1026,13 +1167,7 @@ Returns:
|
|||
LinkQtdToQtd (PreQtdPtr, QtdPtr);
|
||||
}
|
||||
|
||||
//
|
||||
// Reverse Data Toggle or not determined by parity of transactions of one qtd
|
||||
//
|
||||
Xnum = Translator ? GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE_WITH_TT) : GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE);
|
||||
if (Xnum % 2 != 0) {
|
||||
DataToggle ^= 1;
|
||||
}
|
||||
DataToggle ^= 1;
|
||||
|
||||
PreQtdPtr = QtdPtr;
|
||||
DataCursor += SizePerQtd;
|
||||
|
@ -1170,7 +1305,7 @@ Returns:
|
|||
//
|
||||
// Set Alternate Qtd
|
||||
//
|
||||
if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {
|
||||
if (INPUT_PACKET_ID == PktId && 0 < GetNumberOfQtd (FirstQtdPtr)) {
|
||||
Status = CreateAltQtd (
|
||||
HcDev,
|
||||
PktId,
|
||||
|
@ -1262,8 +1397,6 @@ Returns:
|
|||
Count = 0;
|
||||
QtdPtr = FirstQtdPtr;
|
||||
|
||||
;
|
||||
|
||||
while (NULL != QtdPtr) {
|
||||
Count++;
|
||||
QtdPtr = QtdPtr->Next;
|
||||
|
@ -1272,33 +1405,6 @@ Returns:
|
|||
return Count;
|
||||
}
|
||||
|
||||
UINTN
|
||||
GetNumberOfTransaction (
|
||||
IN UINTN SizeOfData,
|
||||
IN UINTN SizeOfTransaction
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Number of Transactions in one Qtd
|
||||
|
||||
Arguments:
|
||||
|
||||
SizeOfData - Size of one Qtd
|
||||
SizeOfTransaction - Size of one Transaction
|
||||
|
||||
Returns:
|
||||
|
||||
Number of Transactions in this Qtd
|
||||
|
||||
--*/
|
||||
{
|
||||
|
||||
return ((SizeOfData & (SizeOfTransaction - 1)) ? SizeOfData / SizeOfTransaction + 1 : SizeOfData / SizeOfTransaction);
|
||||
|
||||
}
|
||||
|
||||
UINTN
|
||||
GetCapacityOfQtd (
|
||||
IN UINT8 *BufferCursor
|
||||
|
@ -1320,7 +1426,11 @@ Returns:
|
|||
--*/
|
||||
{
|
||||
|
||||
return (EHCI_MAX_QTD_CAPACITY - (EHCI_BLOCK_SIZE * GetNumberOfTransaction (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor), EHCI_BLOCK_SIZE)));
|
||||
if (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor)) {
|
||||
return EFI_PAGE_SIZE * 4;
|
||||
} else {
|
||||
return EFI_PAGE_SIZE * 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1424,7 +1534,8 @@ Returns:
|
|||
return Value;
|
||||
}
|
||||
|
||||
VOID LinkQtdToQtd (
|
||||
VOID
|
||||
LinkQtdToQtd (
|
||||
IN EHCI_QTD_ENTITY * PreQtdPtr,
|
||||
IN EHCI_QTD_ENTITY * QtdPtr
|
||||
)
|
||||
|
@ -1467,7 +1578,8 @@ Returns:
|
|||
}
|
||||
|
||||
|
||||
VOID LinkQtdsToAltQtd (
|
||||
VOID
|
||||
LinkQtdsToAltQtd (
|
||||
IN EHCI_QTD_ENTITY * FirstQtdPtr,
|
||||
IN EHCI_QTD_ENTITY * AltQtdPtr
|
||||
)
|
||||
|
@ -1560,6 +1672,18 @@ Returns:
|
|||
QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);
|
||||
QhPtr->Qh.NextQtdTerminate = FALSE;
|
||||
|
||||
QhPtr->Qh.AltNextQtdPointer = 0;
|
||||
QhPtr->Qh.AltNextQtdTerminate = TRUE;
|
||||
|
||||
|
||||
if ((QtdPtr->Qtd.PidCode == OUTPUT_PACKET_PID_CODE) &&
|
||||
(QhPtr->TransferType == BULK_TRANSFER)) {
|
||||
//
|
||||
//Start PING first
|
||||
//
|
||||
QhPtr->Qh.Status |= QTD_STATUS_DO_PING;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -1591,9 +1715,23 @@ Returns:
|
|||
ASSERT (HcDev);
|
||||
ASSERT (QhPtr);
|
||||
|
||||
QhPtr->Qh.HeadReclamationFlag = TRUE;
|
||||
|
||||
Status = SetAsyncListAddr (HcDev, QhPtr);
|
||||
//
|
||||
// NULL QH created before
|
||||
//
|
||||
|
||||
HcDev->NULLQH->Next = QhPtr;
|
||||
HcDev->NULLQH->Prev = QhPtr;
|
||||
|
||||
QhPtr->Next = HcDev->NULLQH;
|
||||
QhPtr->Prev = HcDev->NULLQH;
|
||||
|
||||
|
||||
HcDev->NULLQH->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(QhPtr->Qh) >> 5));
|
||||
QhPtr->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(HcDev->NULLQH->Qh) >> 5));
|
||||
|
||||
|
||||
Status = SetAsyncListAddr (HcDev, HcDev->NULLQH);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
|
@ -1609,7 +1747,7 @@ Returns:
|
|||
|
||||
Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));
|
||||
DEBUG ((gEHCDebugLevel, "EHCI: WaitForAsyncScheduleEnable TimeOut"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -1657,23 +1795,37 @@ Returns:
|
|||
ASSERT (HcDev);
|
||||
ASSERT (QhPtr);
|
||||
|
||||
if (QhPtr == QhPtr->Next) {
|
||||
|
||||
Status = DisableAsynchronousSchedule (HcDev);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
HcDev->NULLQH->Next = HcDev->NULLQH;
|
||||
HcDev->NULLQH->Prev = HcDev->NULLQH;
|
||||
|
||||
Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
QhPtr->Next = QhPtr;
|
||||
QhPtr->Prev = QhPtr;
|
||||
|
||||
HcDev->NULLQH->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&(HcDev->NULLQH->Qh) >> 5));
|
||||
|
||||
|
||||
SetAndWaitDoorBell (HcDev, 2 * EHCI_GENERIC_TIMEOUT);
|
||||
|
||||
QhPtr->Qh.QhTerminate = 1;
|
||||
QhPtr->Qh.QhHorizontalPointer = 0;
|
||||
|
||||
|
||||
Status = DisableAsynchronousSchedule (HcDev);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: WaitForAsyncScheduleDisable TimeOut\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
exit:
|
||||
return Status;
|
||||
}
|
||||
|
@ -2107,21 +2259,20 @@ Returns:
|
|||
{
|
||||
UINTN RemainLen;
|
||||
|
||||
RemainLen = DataLen;
|
||||
ASSERT (QtdHwPtr);
|
||||
ASSERT (DataLen <= 5 * EFI_PAGE_SIZE);
|
||||
|
||||
RemainLen = DataLen;
|
||||
//
|
||||
// Allow buffer address range across 4G.
|
||||
// But EFI_USB_MAX_BULK_BUFFER_NUM = 1, so don't allow
|
||||
// seperate buffer array.
|
||||
//
|
||||
|
||||
//
|
||||
// Set BufferPointer0, ExtBufferPointer0 and Offset
|
||||
//
|
||||
QtdHwPtr->BufferPointer0 = (UINT32) (GET_0B_TO_31B (DataPtr) >> 12);
|
||||
QtdHwPtr->BufferPointer0 = (UINT32) (GET_0B_TO_31B (DataPtr) >> EFI_PAGE_SHIFT);
|
||||
QtdHwPtr->CurrentOffset = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);
|
||||
QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);
|
||||
|
||||
//
|
||||
// Set BufferPointer1 and ExtBufferPointer1
|
||||
|
@ -2132,7 +2283,6 @@ Returns:
|
|||
}
|
||||
|
||||
QtdHwPtr->BufferPointer1 = QtdHwPtr->BufferPointer0 + 1;
|
||||
QtdHwPtr->ExtBufferPointer1 = (QtdHwPtr->BufferPointer1 == 0) ? (QtdHwPtr->ExtBufferPointer0 + 1) : QtdHwPtr->ExtBufferPointer0;
|
||||
|
||||
//
|
||||
// Set BufferPointer2 and ExtBufferPointer2
|
||||
|
@ -2143,7 +2293,6 @@ Returns:
|
|||
}
|
||||
|
||||
QtdHwPtr->BufferPointer2 = QtdHwPtr->BufferPointer1 + 1;
|
||||
QtdHwPtr->ExtBufferPointer2 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer1 + 1) : QtdHwPtr->ExtBufferPointer1;
|
||||
|
||||
//
|
||||
// Set BufferPointer3 and ExtBufferPointer3
|
||||
|
@ -2154,7 +2303,6 @@ Returns:
|
|||
}
|
||||
|
||||
QtdHwPtr->BufferPointer3 = QtdHwPtr->BufferPointer2 + 1;
|
||||
QtdHwPtr->ExtBufferPointer3 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer2 + 1) : QtdHwPtr->ExtBufferPointer2;
|
||||
|
||||
//
|
||||
// Set BufferPointer4 and ExtBufferPointer4
|
||||
|
@ -2165,7 +2313,6 @@ Returns:
|
|||
}
|
||||
|
||||
QtdHwPtr->BufferPointer4 = QtdHwPtr->BufferPointer3 + 1;
|
||||
QtdHwPtr->ExtBufferPointer4 = (QtdHwPtr->BufferPointer3 == 0) ? (QtdHwPtr->ExtBufferPointer3 + 1) : QtdHwPtr->ExtBufferPointer3;
|
||||
|
||||
exit:
|
||||
return ;
|
||||
|
@ -2197,6 +2344,7 @@ Returns:
|
|||
|
||||
QtdStatus = (UINT8) (HwQtdPtr->Status);
|
||||
Value = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);
|
||||
//DEBUG ((gEHCErrorLevel, "EHCI: IsQtdStatusActive 0x%X, Address = %x\r\n",HwQtdPtr->Status, HwQtdPtr));
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
@ -2408,7 +2556,7 @@ Returns:
|
|||
DataMap
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));
|
||||
DEBUG ((gEHCDebugLevel, "EHCI: MapDataBuffer Failed\n"));
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -2578,7 +2726,7 @@ Returns:
|
|||
|
||||
Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleDisable TimeOut\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -2605,7 +2753,7 @@ Returns:
|
|||
|
||||
Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleEnable TimeOut\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -2711,11 +2859,6 @@ Returns:
|
|||
QhPtr->Qh.FrameTag = 0;
|
||||
QhPtr->Qh.BufferPointer3 = 0;
|
||||
QhPtr->Qh.BufferPointer4 = 0;
|
||||
QhPtr->Qh.ExtBufferPointer0 = 0;
|
||||
QhPtr->Qh.ExtBufferPointer1 = 0;
|
||||
QhPtr->Qh.ExtBufferPointer2 = 0;
|
||||
QhPtr->Qh.ExtBufferPointer3 = 0;
|
||||
QhPtr->Qh.ExtBufferPointer4 = 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -2829,25 +2972,37 @@ Returns:
|
|||
QtdHwPtr = &(QtdPtr->Qtd);
|
||||
|
||||
while (NULL != QtdHwPtr) {
|
||||
|
||||
if (IsQtdStatusActive (QtdHwPtr)) {
|
||||
*Result |= EFI_USB_ERR_NOTEXECUTE;
|
||||
}
|
||||
|
||||
if (IsQtdStatusHalted (QtdHwPtr)) {
|
||||
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_HALTED 0x%X\n", QtdHwPtr->Status));
|
||||
*Result |= EFI_USB_ERR_STALL;
|
||||
}
|
||||
|
||||
if (IsQtdStatusBufferError (QtdHwPtr)) {
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_BUFFER_ERR 0x%X\n", QtdHwPtr->Status));
|
||||
*Result |= EFI_USB_ERR_BUFFER;
|
||||
}
|
||||
|
||||
if (IsQtdStatusBabbleError (QtdHwPtr)) {
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: StatusBufferError 0x%X\n", QtdHwPtr->Status));
|
||||
*Result |= EFI_USB_ERR_BABBLE;
|
||||
}
|
||||
|
||||
if (IsQtdStatusTransactionError (QtdHwPtr)) {
|
||||
*Result |= EFI_USB_ERR_TIMEOUT;
|
||||
|
||||
//
|
||||
//Exclude Special Case
|
||||
//
|
||||
if (((QtdHwPtr->Status & QTD_STATUS_HALTED) == QTD_STATUS_HALTED) ||
|
||||
((QtdHwPtr->Status & QTD_STATUS_ACTIVE) == QTD_STATUS_ACTIVE) ||
|
||||
((QtdHwPtr->ErrorCount != QTD_ERROR_COUNTER))) {
|
||||
*Result |= EFI_USB_ERR_TIMEOUT;
|
||||
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_TRANSACTION_ERR: 0x%X\n", QtdHwPtr->Status));
|
||||
}
|
||||
}
|
||||
|
||||
ActualLenPerQtd = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;
|
||||
|
@ -2864,16 +3019,21 @@ Returns:
|
|||
break;
|
||||
}
|
||||
|
||||
if ((!IsControl) && (QtdPtr->TotalBytes > 0)) {
|
||||
if ((INPUT_PACKET_PID_CODE == QtdHwPtr->PidCode)&& (QtdPtr->TotalBytes > 0)) {
|
||||
//
|
||||
// Did something, but isn't full workload
|
||||
// Short Packet: IN, Short
|
||||
//
|
||||
DEBUG ((gEHCDebugLevel, "EHCI: Short Packet Status: 0x%x\n", QtdHwPtr->Status));
|
||||
break;
|
||||
}
|
||||
|
||||
(*ErrQtdPos)++;
|
||||
QtdPtr = QtdPtr->Next;
|
||||
QtdHwPtr = &(QtdPtr->Qtd);
|
||||
if (QtdPtr->Next != NULL) {
|
||||
(*ErrQtdPos)++;
|
||||
QtdPtr = QtdPtr->Next;
|
||||
QtdHwPtr = &(QtdPtr->Qtd);
|
||||
} else {
|
||||
QtdHwPtr = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2924,7 +3084,7 @@ Returns:
|
|||
*ActualLen = 0;
|
||||
Finished = FALSE;
|
||||
|
||||
Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
|
||||
Delay = (TimeOut * STALL_1_MILLI_SECOND / 50);
|
||||
|
||||
do {
|
||||
*TransferResult = 0;
|
||||
|
@ -2951,6 +3111,7 @@ Returns:
|
|||
|
||||
if (EFI_USB_NOERROR != *TransferResult) {
|
||||
if (0 == Delay) {
|
||||
DEBUG((gEHCErrorLevel, "EHCI: QTDS TimeOut\n"));
|
||||
Status = EFI_TIMEOUT;
|
||||
} else {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
|
@ -2989,13 +3150,13 @@ Returns:
|
|||
EFI_STATUS Status;
|
||||
USB2_HC_DEV *HcDev;
|
||||
EHCI_ASYNC_REQUEST *AsyncRequestPtr;
|
||||
EHCI_ASYNC_REQUEST *NextPtr;
|
||||
EHCI_QTD_HW *QtdHwPtr;
|
||||
UINTN ErrQtdPos;
|
||||
UINTN ActualLen;
|
||||
UINT32 TransferResult;
|
||||
UINT8 *ReceiveBuffer;
|
||||
UINT8 *ProcessBuffer;
|
||||
EHCI_ASYNC_REQUEST *NextPtr;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
QtdHwPtr = NULL;
|
||||
|
@ -3032,7 +3193,7 @@ Returns:
|
|||
}
|
||||
|
||||
QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);
|
||||
ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << 12) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);
|
||||
ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << EFI_PAGE_SHIFT) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);
|
||||
CopyMem (
|
||||
ProcessBuffer,
|
||||
ReceiveBuffer,
|
||||
|
|
|
@ -485,6 +485,7 @@ UHCIDriverBindingStart (
|
|||
UINTN FlBaseAddrReg;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
USB_HC_DEV *HcDev;
|
||||
UINT64 Supports;
|
||||
|
||||
HcDev = NULL;
|
||||
|
||||
|
@ -510,10 +511,19 @@ UHCIDriverBindingStart (
|
|||
//
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
EfiPciIoAttributeOperationSupported,
|
||||
0,
|
||||
&Supports
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
Supports,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
|
@ -777,6 +787,8 @@ UnInstallUHCInterface (
|
|||
--*/
|
||||
{
|
||||
USB_HC_DEV *HcDev;
|
||||
EFI_STATUS Status;
|
||||
UINT64 Supports;
|
||||
|
||||
HcDev = USB_HC_DEV_FROM_THIS (This);
|
||||
|
||||
|
@ -823,12 +835,21 @@ UnInstallUHCInterface (
|
|||
//
|
||||
// Disable the USB Host Controller
|
||||
//
|
||||
HcDev->PciIo->Attributes (
|
||||
HcDev->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
);
|
||||
Status = HcDev->PciIo->Attributes (
|
||||
HcDev->PciIo,
|
||||
EfiPciIoAttributeOperationSupported,
|
||||
0,
|
||||
&Supports
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||
Status = HcDev->PciIo->Attributes (
|
||||
HcDev->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
Supports,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
gBS->FreePool (HcDev);
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ Abstract:
|
|||
|
||||
#include "bot.h"
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTDebugLevel = EFI_D_INFO;
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTErrorLevel = EFI_D_INFO;
|
||||
//
|
||||
// Function prototypes
|
||||
//
|
||||
|
@ -85,7 +87,7 @@ STATIC
|
|||
EFI_STATUS
|
||||
BotDataPhase (
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
IN UINT32 *DataSize,
|
||||
IN UINTN *DataSize,
|
||||
IN OUT VOID *DataBuffer,
|
||||
IN EFI_USB_DATA_DIRECTION Direction,
|
||||
IN UINT16 Timeout
|
||||
|
@ -94,11 +96,10 @@ BotDataPhase (
|
|||
STATIC
|
||||
EFI_STATUS
|
||||
BotStatusPhase (
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
OUT UINT8 *TransferStatus,
|
||||
IN UINT16 Timeout
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
OUT UINT32 *DataResidue,
|
||||
IN UINT16 Timeout
|
||||
);
|
||||
|
||||
//
|
||||
// USB Atapi protocol prototype
|
||||
//
|
||||
|
@ -193,7 +194,7 @@ BotDriverBindingSupported (
|
|||
//
|
||||
// Check if it is a BOT type Mass Storage Device
|
||||
//
|
||||
if ((InterfaceDescriptor.InterfaceClass != 0x08) ||
|
||||
if ((InterfaceDescriptor.InterfaceClass != MASS_STORAGE_CLASS) ||
|
||||
(InterfaceDescriptor.InterfaceProtocol != BOT)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Exit;
|
||||
|
@ -513,6 +514,38 @@ BotDriverBindingStop (
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ClearBulkInPipe (
|
||||
IN USB_BOT_DEVICE *UsbBotDev
|
||||
)
|
||||
{
|
||||
UINT32 Result;
|
||||
|
||||
return UsbClearEndpointHalt (
|
||||
UsbBotDev->UsbIo,
|
||||
UsbBotDev->BulkInEndpointDescriptor->EndpointAddress,
|
||||
&Result
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ClearBulkOutPipe (
|
||||
IN USB_BOT_DEVICE *UsbBotDev
|
||||
)
|
||||
{
|
||||
UINT32 Result;
|
||||
return UsbClearEndpointHalt (
|
||||
UsbBotDev->UsbIo,
|
||||
UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,
|
||||
&Result
|
||||
);
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
BotRecoveryReset (
|
||||
|
@ -534,13 +567,8 @@ Returns:
|
|||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Result;
|
||||
EFI_USB_DEVICE_REQUEST Request;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT8 EndpointAddr;
|
||||
|
||||
UsbIo = UsbBotDev->UsbIo;
|
||||
|
||||
UINT32 Result;
|
||||
BotReportStatusCode (
|
||||
UsbBotDev->DevicePath,
|
||||
EFI_PROGRESS_CODE,
|
||||
|
@ -555,43 +583,24 @@ Returns:
|
|||
Request.RequestType = 0x21;
|
||||
Request.Request = 0xFF;
|
||||
|
||||
Status = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
&Request,
|
||||
EfiUsbNoData,
|
||||
TIMEOUT_VALUE,
|
||||
NULL,
|
||||
0,
|
||||
&Result
|
||||
);
|
||||
Status = UsbBotDev->UsbIo->UsbControlTransfer (
|
||||
UsbBotDev->UsbIo,
|
||||
&Request,
|
||||
EfiUsbNoData,
|
||||
TIMEOUT_VALUE,
|
||||
NULL,
|
||||
0,
|
||||
&Result
|
||||
);
|
||||
|
||||
gBS->Stall (100 * 1000);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// clear bulk in endpoint stall feature
|
||||
//
|
||||
EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;
|
||||
|
||||
Status = UsbClearEndpointHalt (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&Result
|
||||
);
|
||||
|
||||
//
|
||||
// clear bulk out endpoint stall feature
|
||||
//
|
||||
EndpointAddr = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;
|
||||
Status = UsbClearEndpointHalt (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&Result
|
||||
);
|
||||
}
|
||||
ClearBulkInPipe (UsbBotDev);
|
||||
ClearBulkOutPipe (UsbBotDev);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Bot Protocol Implementation
|
||||
//
|
||||
|
@ -639,7 +648,17 @@ BotCommandPhase (
|
|||
cbw.dCBWSignature = CBWSIG;
|
||||
cbw.dCBWTag = 0x01;
|
||||
cbw.dCBWDataTransferLength = DataTransferLength;
|
||||
cbw.bmCBWFlags = (UINT8) (Direction << 7);
|
||||
switch (Direction) {
|
||||
case EfiUsbDataOut:
|
||||
case EfiUsbNoData:
|
||||
cbw.bmCBWFlags = 0;
|
||||
break;
|
||||
case EfiUsbDataIn:
|
||||
cbw.bmCBWFlags = 0x80;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cbw.bCBWCBLength = CommandSize;
|
||||
|
||||
CopyMem (cbw.CBWCB, Command, CommandSize);
|
||||
|
@ -648,28 +667,20 @@ BotCommandPhase (
|
|||
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
(UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress,
|
||||
UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,
|
||||
&cbw,
|
||||
&DataSize,
|
||||
Timeout,
|
||||
&Result
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Command phase fail, we need to recovery reset this device
|
||||
//
|
||||
BotRecoveryReset (UsbBotDev);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
BotDataPhase (
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
IN UINT32 *DataSize,
|
||||
IN UINTN *DataSize,
|
||||
IN OUT VOID *DataBuffer,
|
||||
IN EFI_USB_DATA_DIRECTION Direction,
|
||||
IN UINT16 Timeout
|
||||
|
@ -695,125 +706,52 @@ BotDataPhase (
|
|||
UINT32 Result;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT8 EndpointAddr;
|
||||
UINTN Remain;
|
||||
UINTN Increment;
|
||||
UINT32 MaxPacketLen;
|
||||
UINT8 *BufferPtr;
|
||||
UINTN TransferredSize;
|
||||
UINTN RetryTimes;
|
||||
UINTN MaxRetry;
|
||||
UINTN BlockSize;
|
||||
UINTN PackageNum;
|
||||
|
||||
UsbIo = UsbBotDev->UsbIo;
|
||||
Remain = *DataSize;
|
||||
BufferPtr = (UINT8 *) DataBuffer;
|
||||
TransferredSize = 0;
|
||||
MaxRetry = 10;
|
||||
PackageNum = 128;
|
||||
|
||||
//
|
||||
// retrieve the the max packet length of the given endpoint
|
||||
//
|
||||
if (Direction == EfiUsbDataIn) {
|
||||
MaxPacketLen = (UsbBotDev->BulkInEndpointDescriptor)->MaxPacketSize;
|
||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
||||
EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;
|
||||
} else {
|
||||
MaxPacketLen = (UsbBotDev->BulkOutEndpointDescriptor)->MaxPacketSize;
|
||||
EndpointAddr = (UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress;
|
||||
EndpointAddr = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;
|
||||
}
|
||||
|
||||
RetryTimes = MaxRetry;
|
||||
BlockSize = PackageNum * MaxPacketLen;
|
||||
while (Remain > 0) {
|
||||
//
|
||||
// Using 15 packets to aVOID Bitstuff error
|
||||
//
|
||||
if (Remain > PackageNum * MaxPacketLen) {
|
||||
Increment = BlockSize;
|
||||
} else {
|
||||
Increment = Remain;
|
||||
}
|
||||
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
BufferPtr,
|
||||
&Increment,
|
||||
Timeout,
|
||||
DataSize,
|
||||
(UINT16)(Timeout),
|
||||
&Result
|
||||
);
|
||||
|
||||
TransferredSize += Increment;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
RetryTimes--;
|
||||
if ((RetryTimes == 0) || ((Result & EFI_USB_ERR_TIMEOUT) == 0)) {
|
||||
goto ErrorExit;
|
||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||
if (Direction == EfiUsbDataIn) {
|
||||
DEBUG((gBOTErrorLevel, "BOT: Data IN Stall, ClearBulkInPipe\n"));
|
||||
ClearBulkInPipe (UsbBotDev);
|
||||
} else {
|
||||
DEBUG((gBOTErrorLevel, "BOT: Data OUT Stall, ClearBulkInPipe\n"));
|
||||
ClearBulkOutPipe (UsbBotDev);
|
||||
}
|
||||
}
|
||||
// BotRecoveryReset (UsbBotDev);
|
||||
}
|
||||
|
||||
TransferredSize -= Increment;
|
||||
continue;
|
||||
} else {
|
||||
//
|
||||
// we try MaxTetry times for every bulk transfer
|
||||
//
|
||||
RetryTimes = MaxRetry;
|
||||
}
|
||||
|
||||
BufferPtr += Increment;
|
||||
Remain -= Increment;
|
||||
if (Increment < BlockSize && TransferredSize <= *DataSize) {
|
||||
//
|
||||
// we get to the end of transter and transter size is
|
||||
// less than requriedsize
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*DataSize = (UINT32) TransferredSize;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ErrorExit:
|
||||
if (Direction == EfiUsbDataIn) {
|
||||
BotReportStatusCode (
|
||||
UsbBotDev->DevicePath,
|
||||
EFI_ERROR_CODE | EFI_ERROR_MINOR,
|
||||
(EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)
|
||||
);
|
||||
} else {
|
||||
BotReportStatusCode (
|
||||
UsbBotDev->DevicePath,
|
||||
EFI_ERROR_CODE | EFI_ERROR_MINOR,
|
||||
(EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)
|
||||
);
|
||||
}
|
||||
|
||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||
//
|
||||
// just endpoint stall happens
|
||||
//
|
||||
UsbClearEndpointHalt (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&Result
|
||||
);
|
||||
}
|
||||
|
||||
*DataSize = (UINT32) TransferredSize;
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
BotStatusPhase (
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
OUT UINT8 *TransferStatus,
|
||||
IN UINT16 Timeout
|
||||
IN USB_BOT_DEVICE *UsbBotDev,
|
||||
OUT UINT32 *DataResidue,
|
||||
IN UINT16 Timeout
|
||||
)
|
||||
/*++
|
||||
|
||||
|
@ -822,7 +760,6 @@ BotStatusPhase (
|
|||
|
||||
Parameters:
|
||||
UsbBotDev - USB_BOT_DEVICE pointer
|
||||
TransferStatus - TransferStatus
|
||||
Timeout - Time out value in milliseconds
|
||||
Return Value:
|
||||
EFI_SUCCESS
|
||||
|
@ -832,47 +769,21 @@ BotStatusPhase (
|
|||
{
|
||||
CSW csw;
|
||||
EFI_STATUS Status;
|
||||
UINT32 Result;
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT8 EndpointAddr;
|
||||
UINTN DataSize;
|
||||
UINT32 Result;
|
||||
UINT8 Index;
|
||||
|
||||
UsbIo = UsbBotDev->UsbIo;
|
||||
EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;
|
||||
|
||||
ZeroMem (&csw, sizeof (CSW));
|
||||
|
||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
||||
|
||||
DataSize = sizeof (CSW);
|
||||
|
||||
//
|
||||
// Get the status field from bulk transfer
|
||||
//
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&csw,
|
||||
&DataSize,
|
||||
Timeout,
|
||||
&Result
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||
//
|
||||
// just endpoint stall happens
|
||||
//
|
||||
UsbClearEndpointHalt (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&Result
|
||||
);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < 3; Index ++) {
|
||||
ZeroMem (&csw, sizeof (CSW));
|
||||
DataSize = sizeof (CSW);
|
||||
Result = 0;
|
||||
|
||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
||||
|
||||
DataSize = sizeof (CSW);
|
||||
Status = UsbIo->UsbBulkTransfer (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
|
@ -883,25 +794,36 @@ BotStatusPhase (
|
|||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||
UsbClearEndpointHalt (
|
||||
UsbIo,
|
||||
EndpointAddr,
|
||||
&Result
|
||||
);
|
||||
DEBUG((gBOTDebugLevel, "BOT: CSW Stall, ClearBulkInPipe\n"));
|
||||
ClearBulkInPipe (UsbBotDev);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (csw.dCSWSignature == CSWSIG) {
|
||||
if (csw.bCSWStatus == 0 || csw.bCSWStatus == 0x01) {
|
||||
if (DataResidue != NULL) {
|
||||
*DataResidue = csw.dCSWDataResidue;
|
||||
}
|
||||
if (csw.bCSWStatus == 0x01) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
break;
|
||||
} else if (csw.bCSWStatus == 0x02) {
|
||||
DEBUG((gBOTErrorLevel, "BOT: Bot Phase error\n"));
|
||||
BotRecoveryReset (UsbBotDev);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (csw.dCSWSignature == CSWSIG) {
|
||||
*TransferStatus = csw.bCSWStatus;
|
||||
} else {
|
||||
if (Index == 3) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Usb Atapi Protocol implementation
|
||||
//
|
||||
|
@ -938,81 +860,82 @@ BotAtapiCommand (
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS BotDataStatus;
|
||||
UINT8 TransferStatus;
|
||||
USB_BOT_DEVICE *UsbBotDev;
|
||||
UINT32 BufferSize;
|
||||
|
||||
BotDataStatus = EFI_SUCCESS;
|
||||
TransferStatus = 0;
|
||||
UINTN BufferSize;
|
||||
UINT8 Index;
|
||||
UINT32 DataResidue;
|
||||
|
||||
//
|
||||
// Get the context
|
||||
//
|
||||
UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);
|
||||
UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);
|
||||
BotDataStatus = EFI_SUCCESS;
|
||||
BufferSize = 0;
|
||||
|
||||
//
|
||||
// First send ATAPI command through Bot
|
||||
//
|
||||
Status = BotCommandPhase (
|
||||
UsbBotDev,
|
||||
Command,
|
||||
CommandSize,
|
||||
BufferLength,
|
||||
Direction,
|
||||
TimeOutInMilliSeconds
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Send/Get Data if there is a Data Stage
|
||||
//
|
||||
switch (Direction) {
|
||||
|
||||
case EfiUsbDataIn:
|
||||
case EfiUsbDataOut:
|
||||
BufferSize = BufferLength;
|
||||
|
||||
BotDataStatus = BotDataPhase (
|
||||
UsbBotDev,
|
||||
&BufferSize,
|
||||
DataBuffer,
|
||||
Direction,
|
||||
(UINT16) (TimeOutInMilliSeconds)
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case EfiUsbNoData:
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Status Phase
|
||||
//
|
||||
Status = BotStatusPhase (
|
||||
UsbBotDev,
|
||||
&TransferStatus,
|
||||
TimeOutInMilliSeconds
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (TransferStatus == 0x02) {
|
||||
for (Index = 0; Index < 3; Index ++) {
|
||||
//
|
||||
// Phase error
|
||||
// First send ATAPI command through Bot
|
||||
//
|
||||
BotRecoveryReset (UsbBotDev);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
Status = BotCommandPhase (
|
||||
UsbBotDev,
|
||||
Command,
|
||||
CommandSize,
|
||||
BufferLength,
|
||||
Direction,
|
||||
10 * 1000
|
||||
);
|
||||
|
||||
if (TransferStatus == 0x01) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG((gBOTErrorLevel, "BotCommandPhase Fail\n"));
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Send/Get Data if there is a Data Stage
|
||||
//
|
||||
switch (Direction) {
|
||||
|
||||
case EfiUsbDataIn:
|
||||
case EfiUsbDataOut:
|
||||
BufferSize = BufferLength;
|
||||
|
||||
BotDataStatus = BotDataPhase (
|
||||
UsbBotDev,
|
||||
&BufferSize,
|
||||
DataBuffer,
|
||||
Direction,
|
||||
(UINT16) (TimeOutInMilliSeconds)
|
||||
);
|
||||
|
||||
|
||||
if (EFI_ERROR (BotDataStatus)) {
|
||||
DEBUG((gBOTErrorLevel, "BotDataPhase Fail\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiUsbNoData:
|
||||
break;
|
||||
}
|
||||
|
||||
DataResidue = 0;
|
||||
//
|
||||
// Status Phase
|
||||
//
|
||||
Status = BotStatusPhase (
|
||||
UsbBotDev,
|
||||
&DataResidue,
|
||||
10 * 1000
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG((gBOTErrorLevel, "BotStatusPhase Fail\n"));
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (BotDataStatus)) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return BotDataStatus;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ Abstract:
|
|||
|
||||
|
||||
#include <IndustryStandard/Usb.h>
|
||||
extern UINT32 gBOTDebugLevel;
|
||||
extern UINT32 gBOTErrorLevel;
|
||||
#define MASS_STORAGE_CLASS 0x08
|
||||
|
||||
#pragma pack(1)
|
||||
//
|
||||
|
|
|
@ -396,7 +396,7 @@ USBFloppyReset (
|
|||
//
|
||||
// directly calling EFI_USB_ATAPI_PROTOCOL.Reset() to implement reset.
|
||||
//
|
||||
Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, TRUE);
|
||||
Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, ExtendedVerification);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -442,12 +442,9 @@ USBFloppyReadBlocks (
|
|||
UINTN BlockSize;
|
||||
UINTN NumberOfBlocks;
|
||||
BOOLEAN MediaChange;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
||||
Status = EFI_SUCCESS;
|
||||
MediaChange = FALSE;
|
||||
|
||||
UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);
|
||||
|
||||
//
|
||||
|
@ -473,14 +470,12 @@ USBFloppyReadBlocks (
|
|||
}
|
||||
|
||||
if (MediaChange) {
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
gBS->ReinstallProtocolInterface (
|
||||
UsbFloppyDevice->Handle,
|
||||
&gEfiBlockIoProtocolGuid,
|
||||
&UsbFloppyDevice->BlkIo,
|
||||
&UsbFloppyDevice->BlkIo
|
||||
);
|
||||
gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
||||
}
|
||||
|
||||
Media = UsbFloppyDevice->BlkIo.Media;
|
||||
|
@ -517,33 +512,31 @@ USBFloppyReadBlocks (
|
|||
goto Done;
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
while (NumberOfBlocks > 0) {
|
||||
|
||||
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, 1);
|
||||
if (EFI_ERROR (Status)) {
|
||||
This->Reset (This, TRUE);
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Done;
|
||||
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
|
||||
} else {
|
||||
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||
}
|
||||
|
||||
LBA += 1;
|
||||
NumberOfBlocks -= 1;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize;
|
||||
|
||||
if (NumberOfBlocks == 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||
if (EFI_ERROR (Status)) {
|
||||
This->Reset (This, TRUE);
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||
NumberOfBlocks -= BLOCK_UNIT;
|
||||
LBA += BLOCK_UNIT;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize * BLOCK_UNIT;
|
||||
} else {
|
||||
NumberOfBlocks -= NumberOfBlocks;
|
||||
LBA += NumberOfBlocks;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize * NumberOfBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -591,9 +584,7 @@ USBFloppyWriteBlocks (
|
|||
UINTN BlockSize;
|
||||
UINTN NumberOfBlocks;
|
||||
BOOLEAN MediaChange;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
||||
Status = EFI_SUCCESS;
|
||||
MediaChange = FALSE;
|
||||
|
||||
|
@ -622,14 +613,12 @@ USBFloppyWriteBlocks (
|
|||
}
|
||||
|
||||
if (MediaChange) {
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
gBS->ReinstallProtocolInterface (
|
||||
UsbFloppyDevice->Handle,
|
||||
&gEfiBlockIoProtocolGuid,
|
||||
&UsbFloppyDevice->BlkIo,
|
||||
&UsbFloppyDevice->BlkIo
|
||||
);
|
||||
gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
||||
}
|
||||
|
||||
Media = UsbFloppyDevice->BlkIo.Media;
|
||||
|
@ -671,32 +660,32 @@ USBFloppyWriteBlocks (
|
|||
goto Done;
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, 1);
|
||||
if (EFI_ERROR (Status)) {
|
||||
This->Reset (This, TRUE);
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Done;
|
||||
while (NumberOfBlocks > 0) {
|
||||
|
||||
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
|
||||
} else {
|
||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||
}
|
||||
|
||||
LBA += 1;
|
||||
NumberOfBlocks -= 1;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize;
|
||||
|
||||
if (NumberOfBlocks == 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||
if (EFI_ERROR (Status)) {
|
||||
This->Reset (This, TRUE);
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||
NumberOfBlocks -= BLOCK_UNIT;
|
||||
LBA += BLOCK_UNIT;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize * BLOCK_UNIT;
|
||||
} else {
|
||||
NumberOfBlocks -= NumberOfBlocks;
|
||||
LBA += NumberOfBlocks;
|
||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize * NumberOfBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ Revision History
|
|||
#define USBFLOPPY2 2 // for those that use ReadFormatCapacity(0x23) command to retrieve media capacity
|
||||
#define USBCDROM 3
|
||||
|
||||
#define BLOCK_UNIT 128
|
||||
|
||||
#define USB_FLOPPY_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'f', 'l', 'p')
|
||||
|
||||
typedef struct {
|
||||
|
@ -50,7 +52,6 @@ typedef struct {
|
|||
REQUEST_SENSE_DATA *SenseData;
|
||||
UINT8 SenseDataNumber;
|
||||
UINT8 DeviceType;
|
||||
|
||||
} USB_FLOPPY_DEV;
|
||||
|
||||
#define USB_FLOPPY_DEV_FROM_THIS(a) \
|
||||
|
|
|
@ -30,7 +30,7 @@ Revision History
|
|||
//
|
||||
// timeout unit is in millisecond.
|
||||
//
|
||||
#define USBFLPTIMEOUT 2000
|
||||
#define USBFLPTIMEOUT 1000
|
||||
#define STALL_1_MILLI_SECOND 1000
|
||||
|
||||
//
|
||||
|
|
|
@ -272,10 +272,10 @@ USBFloppyInquiry (
|
|||
|
||||
EFI_STATUS
|
||||
USBFloppyRead10 (
|
||||
IN USB_FLOPPY_DEV *UsbFloppyDevice,
|
||||
IN VOID *Buffer,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN NumberOfBlocks
|
||||
IN USB_FLOPPY_DEV *UsbFloppyDevice,
|
||||
IN VOID *Buffer,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN NumberOfBlocks
|
||||
)
|
||||
/*++
|
||||
|
||||
|
@ -310,7 +310,7 @@ USBFloppyRead10 (
|
|||
EFI_STATUS Status;
|
||||
UINT16 TimeOut;
|
||||
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
||||
UINTN SenseCounts;
|
||||
UINT8 Index;
|
||||
|
||||
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
||||
|
||||
|
@ -333,78 +333,52 @@ USBFloppyRead10 (
|
|||
} 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);
|
||||
for (Index = 0; Index < 3; Index ++) {
|
||||
|
||||
//
|
||||
// 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
|
||||
// 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)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
UsbFloppyDevice,
|
||||
&Packet,
|
||||
sizeof (ATAPI_PACKET_COMMAND),
|
||||
(VOID *) ptrBuffer,
|
||||
ByteCount,
|
||||
EfiUsbDataIn,
|
||||
TimeOut
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == 3) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Lba32 += SectorCount;
|
||||
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
||||
BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
|
||||
|
@ -737,10 +711,10 @@ UsbFloppyTestUnitReady (
|
|||
|
||||
EFI_STATUS
|
||||
USBFloppyWrite10 (
|
||||
IN USB_FLOPPY_DEV *UsbFloppyDevice,
|
||||
IN VOID *Buffer,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN NumberOfBlocks
|
||||
IN USB_FLOPPY_DEV *UsbFloppyDevice,
|
||||
IN VOID *Buffer,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN NumberOfBlocks
|
||||
)
|
||||
/*++
|
||||
|
||||
|
@ -775,7 +749,7 @@ USBFloppyWrite10 (
|
|||
EFI_STATUS Status;
|
||||
UINT16 TimeOut;
|
||||
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
||||
UINTN SenseCounts;
|
||||
UINT8 Index;
|
||||
|
||||
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
||||
|
||||
|
@ -795,82 +769,56 @@ USBFloppyWrite10 (
|
|||
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;
|
||||
}
|
||||
}
|
||||
for (Index = 0; Index < 3; Index ++) {
|
||||
//
|
||||
// retry write10 command
|
||||
// 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)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
UsbFloppyDevice,
|
||||
&Packet,
|
||||
sizeof (ATAPI_PACKET_COMMAND),
|
||||
(VOID *) ptrBuffer,
|
||||
ByteCount,
|
||||
EfiUsbDataOut,
|
||||
TimeOut
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == 3) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Lba32 += SectorCount;
|
||||
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
||||
BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
|
||||
|
@ -910,11 +858,10 @@ UsbFloppyDetectMedia (
|
|||
UINTN RetryTimes;
|
||||
UINTN MaximumRetryTimes;
|
||||
BOOLEAN NeedRetry;
|
||||
|
||||
BOOLEAN NeedReadCapacity;
|
||||
//
|
||||
// a flag used to determine whether need to perform Read Capacity command.
|
||||
//
|
||||
BOOLEAN NeedReadCapacity;
|
||||
|
||||
REQUEST_SENSE_DATA *SensePtr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue