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"
|
#include "Ehci.h"
|
||||||
|
|
||||||
void
|
|
||||||
|
VOID
|
||||||
DumpEHCIPortsStatus (
|
DumpEHCIPortsStatus (
|
||||||
IN USB2_HC_DEV *HcDev
|
IN USB2_HC_DEV *HcDev
|
||||||
)
|
)
|
||||||
|
@ -47,6 +48,8 @@ DumpEHCIPortsStatus (
|
||||||
);
|
);
|
||||||
DEBUG((gEHCDebugLevel, "Port[%d] = 0x%x\n", Index, Value));
|
DEBUG((gEHCDebugLevel, "Port[%d] = 0x%x\n", Index, Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ Revision History
|
||||||
#include "Ehci.h"
|
#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;
|
GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCErrorLevel = EFI_D_ERROR;
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,6 +353,7 @@ EhciDriverBindingStart (
|
||||||
UINT8 MaxSpeed;
|
UINT8 MaxSpeed;
|
||||||
UINT8 PortNumber;
|
UINT8 PortNumber;
|
||||||
UINT8 Is64BitCapable;
|
UINT8 Is64BitCapable;
|
||||||
|
UINT64 Supports;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open the PciIo Protocol
|
// Open the PciIo Protocol
|
||||||
|
@ -373,12 +374,21 @@ EhciDriverBindingStart (
|
||||||
//
|
//
|
||||||
// Enable the USB Host Controller
|
// Enable the USB Host Controller
|
||||||
//
|
//
|
||||||
|
Status = PciIo->Attributes (
|
||||||
|
PciIo,
|
||||||
|
EfiPciIoAttributeOperationSupported,
|
||||||
|
0,
|
||||||
|
&Supports
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
Status = PciIo->Attributes (
|
Status = PciIo->Attributes (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoAttributeOperationEnable,
|
EfiPciIoAttributeOperationEnable,
|
||||||
EFI_PCI_DEVICE_ENABLE,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto close_pciio_protocol;
|
goto close_pciio_protocol;
|
||||||
|
@ -483,13 +493,18 @@ EhciDriverBindingStart (
|
||||||
goto deinit_perodic_frame_list;
|
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
|
// Create AsyncRequest Polling Timer
|
||||||
//
|
//
|
||||||
Status = CreatePollingTimer (HcDev, (EFI_EVENT_NOTIFY) AsyncRequestMoniter);
|
Status = CreatePollingTimer (HcDev, (EFI_EVENT_NOTIFY) AsyncRequestMoniter);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto deinit_memory_management;
|
goto deinit_null_qh;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -538,7 +553,8 @@ EhciDriverBindingStart (
|
||||||
//
|
//
|
||||||
deinit_timer:
|
deinit_timer:
|
||||||
DestoryPollingTimer (HcDev);
|
DestoryPollingTimer (HcDev);
|
||||||
deinit_memory_management:
|
deinit_null_qh:
|
||||||
|
DestroyNULLQH(HcDev);
|
||||||
DeinitialMemoryManagement (HcDev);
|
DeinitialMemoryManagement (HcDev);
|
||||||
deinit_perodic_frame_list:
|
deinit_perodic_frame_list:
|
||||||
DeinitialPeriodicFrameList (HcDev);
|
DeinitialPeriodicFrameList (HcDev);
|
||||||
|
@ -593,6 +609,7 @@ EhciDriverBindingStop (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_USB2_HC_PROTOCOL *Usb2Hc;
|
EFI_USB2_HC_PROTOCOL *Usb2Hc;
|
||||||
USB2_HC_DEV *HcDev;
|
USB2_HC_DEV *HcDev;
|
||||||
|
UINT64 Supports;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Test whether the Controller handler passed in is a valid
|
// Test whether the Controller handler passed in is a valid
|
||||||
|
@ -658,6 +675,11 @@ EhciDriverBindingStop (
|
||||||
//
|
//
|
||||||
DeinitialPeriodicFrameList (HcDev);
|
DeinitialPeriodicFrameList (HcDev);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy NULLQH
|
||||||
|
//
|
||||||
|
DestroyNULLQH (HcDev);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Deinit Ehci pool memory management
|
// Deinit Ehci pool memory management
|
||||||
//
|
//
|
||||||
|
@ -671,12 +693,21 @@ EhciDriverBindingStop (
|
||||||
//
|
//
|
||||||
// Disable the USB Host Controller
|
// Disable the USB Host Controller
|
||||||
//
|
//
|
||||||
|
Status = HcDev->PciIo->Attributes (
|
||||||
|
HcDev->PciIo,
|
||||||
|
EfiPciIoAttributeOperationSupported,
|
||||||
|
0,
|
||||||
|
&Supports
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
Status = HcDev->PciIo->Attributes (
|
Status = HcDev->PciIo->Attributes (
|
||||||
HcDev->PciIo,
|
HcDev->PciIo,
|
||||||
EfiPciIoAttributeOperationDisable,
|
EfiPciIoAttributeOperationDisable,
|
||||||
EFI_PCI_DEVICE_ENABLE,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
@ -36,6 +36,9 @@ extern UINTN gEHCErrorLevel;
|
||||||
#define STALL_1_MILLI_SECOND 1000 * STALL_1_MACRO_SECOND
|
#define STALL_1_MILLI_SECOND 1000 * STALL_1_MACRO_SECOND
|
||||||
#define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND
|
#define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND
|
||||||
|
|
||||||
|
#define MEM_UNIT_SIZE 128
|
||||||
|
|
||||||
|
|
||||||
#define SETUP_PACKET_PID_CODE 0x02
|
#define SETUP_PACKET_PID_CODE 0x02
|
||||||
#define INPUT_PACKET_PID_CODE 0x01
|
#define INPUT_PACKET_PID_CODE 0x01
|
||||||
#define OUTPUT_PACKET_PID_CODE 0x0
|
#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 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_MIN_PACKET_SIZE 8
|
||||||
#define EHCI_MAX_PACKET_SIZE 1024
|
#define EHCI_MAX_PACKET_SIZE 1024
|
||||||
|
@ -64,7 +67,7 @@ extern UINTN gEHCErrorLevel;
|
||||||
#define EHCI_MAX_QTD_CAPACITY (EFI_PAGE_SIZE * 5)
|
#define EHCI_MAX_QTD_CAPACITY (EFI_PAGE_SIZE * 5)
|
||||||
|
|
||||||
#define NAK_COUNT_RELOAD 3
|
#define NAK_COUNT_RELOAD 3
|
||||||
#define QTD_ERROR_COUNTER 1
|
#define QTD_ERROR_COUNTER 3
|
||||||
#define HIGH_BANDWIDTH_PIPE_MULTIPLIER 1
|
#define HIGH_BANDWIDTH_PIPE_MULTIPLIER 1
|
||||||
|
|
||||||
#define QTD_STATUS_ACTIVE 0x80
|
#define QTD_STATUS_ACTIVE 0x80
|
||||||
|
@ -210,6 +213,9 @@ typedef struct {
|
||||||
UINT8 BaseCode;
|
UINT8 BaseCode;
|
||||||
} USB_CLASSC;
|
} USB_CLASSC;
|
||||||
|
|
||||||
|
//
|
||||||
|
//32 Bytes Aligned
|
||||||
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 NextQtdTerminate : 1;
|
UINT32 NextQtdTerminate : 1;
|
||||||
UINT32 Rsvd1 : 4;
|
UINT32 Rsvd1 : 4;
|
||||||
|
@ -242,13 +248,12 @@ typedef struct {
|
||||||
UINT32 Rsvd6 : 12;
|
UINT32 Rsvd6 : 12;
|
||||||
UINT32 BufferPointer4 : 20;
|
UINT32 BufferPointer4 : 20;
|
||||||
|
|
||||||
UINT32 ExtBufferPointer0;
|
UINT32 PAD[5];
|
||||||
UINT32 ExtBufferPointer1;
|
|
||||||
UINT32 ExtBufferPointer2;
|
|
||||||
UINT32 ExtBufferPointer3;
|
|
||||||
UINT32 ExtBufferPointer4;
|
|
||||||
} EHCI_QTD_HW;
|
} EHCI_QTD_HW;
|
||||||
|
|
||||||
|
//
|
||||||
|
//32 Bytes Aligned
|
||||||
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 QhTerminate : 1;
|
UINT32 QhTerminate : 1;
|
||||||
UINT32 SelectType : 2;
|
UINT32 SelectType : 2;
|
||||||
|
@ -307,11 +312,7 @@ typedef struct {
|
||||||
UINT32 Rsvd6 : 12;
|
UINT32 Rsvd6 : 12;
|
||||||
UINT32 BufferPointer4 : 20;
|
UINT32 BufferPointer4 : 20;
|
||||||
|
|
||||||
UINT32 ExtBufferPointer0;
|
UINT32 Pad[5];
|
||||||
UINT32 ExtBufferPointer1;
|
|
||||||
UINT32 ExtBufferPointer2;
|
|
||||||
UINT32 ExtBufferPointer3;
|
|
||||||
UINT32 ExtBufferPointer4;
|
|
||||||
} EHCI_QH_HW;
|
} EHCI_QH_HW;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -326,7 +327,9 @@ typedef struct {
|
||||||
typedef struct _EHCI_QTD_ENTITY EHCI_QTD_ENTITY;
|
typedef struct _EHCI_QTD_ENTITY EHCI_QTD_ENTITY;
|
||||||
typedef struct _EHCI_QH_ENTITY EHCI_QH_ENTITY;
|
typedef struct _EHCI_QH_ENTITY EHCI_QH_ENTITY;
|
||||||
typedef struct _EHCI_ASYNC_REQUEST EHCI_ASYNC_REQUEST;
|
typedef struct _EHCI_ASYNC_REQUEST EHCI_ASYNC_REQUEST;
|
||||||
|
//
|
||||||
|
//Aligan On 32 Bytes
|
||||||
|
//
|
||||||
struct _EHCI_QTD_ENTITY {
|
struct _EHCI_QTD_ENTITY {
|
||||||
EHCI_QTD_HW Qtd;
|
EHCI_QTD_HW Qtd;
|
||||||
UINT32 TotalBytes;
|
UINT32 TotalBytes;
|
||||||
|
@ -337,7 +340,9 @@ struct _EHCI_QTD_ENTITY {
|
||||||
EHCI_QTD_ENTITY *AltNext;
|
EHCI_QTD_ENTITY *AltNext;
|
||||||
EHCI_QH_ENTITY *SelfQh;
|
EHCI_QH_ENTITY *SelfQh;
|
||||||
};
|
};
|
||||||
|
//
|
||||||
|
//Aligan On 32 Bytes
|
||||||
|
//
|
||||||
struct _EHCI_QH_ENTITY {
|
struct _EHCI_QH_ENTITY {
|
||||||
EHCI_QH_HW Qh;
|
EHCI_QH_HW Qh;
|
||||||
EHCI_QH_ENTITY *Next;
|
EHCI_QH_ENTITY *Next;
|
||||||
|
@ -392,6 +397,7 @@ typedef struct _USB2_HC_DEV {
|
||||||
MEMORY_MANAGE_HEADER *MemoryHeader;
|
MEMORY_MANAGE_HEADER *MemoryHeader;
|
||||||
UINT8 Is64BitCapable;
|
UINT8 Is64BitCapable;
|
||||||
UINT32 High32BitAddr;
|
UINT32 High32BitAddr;
|
||||||
|
EHCI_QH_ENTITY *NULLQH;
|
||||||
UINT32 UsbCapabilityLen;
|
UINT32 UsbCapabilityLen;
|
||||||
UINT16 DeviceSpeed[16];
|
UINT16 DeviceSpeed[16];
|
||||||
} USB2_HC_DEV;
|
} 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
|
UINTN
|
||||||
GetCapacityOfQtd (
|
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
|
VOID
|
||||||
ClearLegacySupport (
|
ClearLegacySupport (
|
||||||
IN USB2_HC_DEV *HcDev
|
IN USB2_HC_DEV *HcDev
|
||||||
|
@ -2692,8 +2703,11 @@ HostReset (
|
||||||
IN USB2_HC_DEV *HcDev
|
IN USB2_HC_DEV *HcDev
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DumpEHCIPortsStatus (
|
DumpEHCIPortsStatus (
|
||||||
IN USB2_HC_DEV *HcDev
|
IN USB2_HC_DEV *HcDev
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,7 +73,7 @@ Returns:
|
||||||
//
|
//
|
||||||
// each bit in Bit Array will manage 32 bytes memory in memory block
|
// 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
|
// Allocate memory for BitArray
|
||||||
|
@ -244,8 +244,8 @@ Returns:
|
||||||
//
|
//
|
||||||
// allocate unit is 32 bytes (align on 32 byte)
|
// allocate unit is 32 bytes (align on 32 byte)
|
||||||
//
|
//
|
||||||
if (AllocSize & 0x1F) {
|
if (AllocSize & (MEM_UNIT_SIZE - 1)) {
|
||||||
RealAllocSize = (AllocSize / 32 + 1) * 32;
|
RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
|
||||||
} else {
|
} else {
|
||||||
RealAllocSize = AllocSize;
|
RealAllocSize = AllocSize;
|
||||||
}
|
}
|
||||||
|
@ -262,17 +262,21 @@ Returns:
|
||||||
Status = AllocMemInMemoryBlock (
|
Status = AllocMemInMemoryBlock (
|
||||||
TempHeaderPtr,
|
TempHeaderPtr,
|
||||||
(VOID **) Pool,
|
(VOID **) Pool,
|
||||||
RealAllocSize / 32
|
RealAllocSize / MEM_UNIT_SIZE
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
ZeroMem (*Pool, AllocSize);
|
break;
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
ZeroMem (*Pool, AllocSize);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// There is no enough memory,
|
// There is no enough memory,
|
||||||
// Create a new Memory Block
|
// Create a new Memory Block
|
||||||
|
@ -303,13 +307,15 @@ Returns:
|
||||||
Status = AllocMemInMemoryBlock (
|
Status = AllocMemInMemoryBlock (
|
||||||
NewMemoryHeader,
|
NewMemoryHeader,
|
||||||
(VOID **) Pool,
|
(VOID **) Pool,
|
||||||
RealAllocSize / 32
|
RealAllocSize / MEM_UNIT_SIZE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
ZeroMem (*Pool, AllocSize);
|
ZeroMem (*Pool, AllocSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,8 +360,8 @@ Returns:
|
||||||
//
|
//
|
||||||
// allocate unit is 32 byte (align on 32 byte)
|
// allocate unit is 32 byte (align on 32 byte)
|
||||||
//
|
//
|
||||||
if (AllocSize & 0x1F) {
|
if (AllocSize & (MEM_UNIT_SIZE - 1)) {
|
||||||
RealAllocSize = (AllocSize / 32 + 1) * 32;
|
RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
|
||||||
} else {
|
} else {
|
||||||
RealAllocSize = AllocSize;
|
RealAllocSize = AllocSize;
|
||||||
}
|
}
|
||||||
|
@ -373,14 +379,16 @@ Returns:
|
||||||
// Pool is in the Memory Block area,
|
// Pool is in the Memory Block area,
|
||||||
// find the start byte and bit in the bit array
|
// find the start byte and bit in the bit array
|
||||||
//
|
//
|
||||||
StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;
|
StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) / 8;
|
||||||
StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);
|
StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) & 0x7);
|
||||||
|
|
||||||
//
|
//
|
||||||
// reset associated bits in bit arry
|
// reset associated bits in bit arry
|
||||||
//
|
//
|
||||||
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {
|
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / MEM_UNIT_SIZE); Count++) {
|
||||||
TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ (bit (Index2)));
|
ASSERT ((TempHeaderPtr->BitArrayPtr[Index] & bit (Index2) )== bit (Index2));
|
||||||
|
|
||||||
|
TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));
|
||||||
Index2++;
|
Index2++;
|
||||||
if (Index2 == 8) {
|
if (Index2 == 8) {
|
||||||
Index += 1;
|
Index += 1;
|
||||||
|
@ -508,7 +516,7 @@ Returns:
|
||||||
//
|
//
|
||||||
// right shift the byte
|
// right shift the byte
|
||||||
//
|
//
|
||||||
ByteValue /= 2;
|
ByteValue = ByteValue >> 1;
|
||||||
|
|
||||||
if (BitValue == 0) {
|
if (BitValue == 0) {
|
||||||
//
|
//
|
||||||
|
@ -595,7 +603,8 @@ Returns:
|
||||||
//
|
//
|
||||||
for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
|
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++;
|
Index++;
|
||||||
if (Index == 8) {
|
if (Index == 8) {
|
||||||
TempBytePos += 1;
|
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;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -675,6 +684,7 @@ Returns:
|
||||||
// Link the before and after
|
// Link the before and after
|
||||||
//
|
//
|
||||||
TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
|
TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
|
||||||
|
NeedFreeMemoryHeader->Next = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,8 @@ Returns:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ClearLegacySupport (
|
ClearLegacySupport (
|
||||||
IN USB2_HC_DEV *HcDev
|
IN USB2_HC_DEV *HcDev
|
||||||
|
|
|
@ -21,6 +21,155 @@ Revision History
|
||||||
|
|
||||||
#include "Ehci.h"
|
#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
|
EFI_STATUS
|
||||||
InitialPeriodicFrameList (
|
InitialPeriodicFrameList (
|
||||||
IN USB2_HC_DEV *HcDev,
|
IN USB2_HC_DEV *HcDev,
|
||||||
|
@ -337,10 +486,6 @@ Returns:
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Init fields in Qh
|
|
||||||
//
|
|
||||||
ZeroMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Software field
|
// Software field
|
||||||
|
@ -359,8 +504,8 @@ Returns:
|
||||||
QhHwPtr->SelectType = 0;
|
QhHwPtr->SelectType = 0;
|
||||||
QhHwPtr->MaxPacketLen = (UINT32) MaxPacketLen;
|
QhHwPtr->MaxPacketLen = (UINT32) MaxPacketLen;
|
||||||
QhHwPtr->EndpointSpeed = (DeviceSpeed & 0x3);
|
QhHwPtr->EndpointSpeed = (DeviceSpeed & 0x3);
|
||||||
QhHwPtr->EndpointNum = (Endpoint & 0x0f);
|
QhHwPtr->EndpointNum = (Endpoint & 0x0F);
|
||||||
QhHwPtr->DeviceAddr = (DeviceAddr & 0x7f);
|
QhHwPtr->DeviceAddr = (DeviceAddr & 0x7F);
|
||||||
QhHwPtr->Multiplier = HIGH_BANDWIDTH_PIPE_MULTIPLIER;
|
QhHwPtr->Multiplier = HIGH_BANDWIDTH_PIPE_MULTIPLIER;
|
||||||
QhHwPtr->Rsvd1 = 0;
|
QhHwPtr->Rsvd1 = 0;
|
||||||
QhHwPtr->Rsvd2 = 0;
|
QhHwPtr->Rsvd2 = 0;
|
||||||
|
@ -467,7 +612,9 @@ Returns:
|
||||||
(*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
|
(*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
|
||||||
(*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
|
(*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
|
||||||
(*QhPtrPtr)->Qh.QhTerminate = FALSE;
|
(*QhPtrPtr)->Qh.QhTerminate = FALSE;
|
||||||
|
if (EFI_USB_SPEED_HIGH != DeviceSpeed) {
|
||||||
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
|
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
|
||||||
|
}
|
||||||
(*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
|
(*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
|
||||||
if (NULL != Translator) {
|
if (NULL != Translator) {
|
||||||
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
|
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
|
||||||
|
@ -696,11 +843,6 @@ Returns:
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Init fields in Qtd
|
|
||||||
//
|
|
||||||
|
|
||||||
ZeroMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Software field
|
// Software field
|
||||||
|
@ -961,7 +1103,6 @@ Returns:
|
||||||
UINTN CapacityOfQtd;
|
UINTN CapacityOfQtd;
|
||||||
UINTN SizePerQtd;
|
UINTN SizePerQtd;
|
||||||
UINTN DataCount;
|
UINTN DataCount;
|
||||||
UINTN Xnum;
|
|
||||||
|
|
||||||
QtdPtr = NULL;
|
QtdPtr = NULL;
|
||||||
PreQtdPtr = NULL;
|
PreQtdPtr = NULL;
|
||||||
|
@ -1026,13 +1167,7 @@ Returns:
|
||||||
LinkQtdToQtd (PreQtdPtr, QtdPtr);
|
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;
|
PreQtdPtr = QtdPtr;
|
||||||
DataCursor += SizePerQtd;
|
DataCursor += SizePerQtd;
|
||||||
|
@ -1170,7 +1305,7 @@ Returns:
|
||||||
//
|
//
|
||||||
// Set Alternate Qtd
|
// Set Alternate Qtd
|
||||||
//
|
//
|
||||||
if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {
|
if (INPUT_PACKET_ID == PktId && 0 < GetNumberOfQtd (FirstQtdPtr)) {
|
||||||
Status = CreateAltQtd (
|
Status = CreateAltQtd (
|
||||||
HcDev,
|
HcDev,
|
||||||
PktId,
|
PktId,
|
||||||
|
@ -1262,8 +1397,6 @@ Returns:
|
||||||
Count = 0;
|
Count = 0;
|
||||||
QtdPtr = FirstQtdPtr;
|
QtdPtr = FirstQtdPtr;
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
while (NULL != QtdPtr) {
|
while (NULL != QtdPtr) {
|
||||||
Count++;
|
Count++;
|
||||||
QtdPtr = QtdPtr->Next;
|
QtdPtr = QtdPtr->Next;
|
||||||
|
@ -1272,33 +1405,6 @@ Returns:
|
||||||
return Count;
|
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
|
UINTN
|
||||||
GetCapacityOfQtd (
|
GetCapacityOfQtd (
|
||||||
IN UINT8 *BufferCursor
|
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;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID LinkQtdToQtd (
|
VOID
|
||||||
|
LinkQtdToQtd (
|
||||||
IN EHCI_QTD_ENTITY * PreQtdPtr,
|
IN EHCI_QTD_ENTITY * PreQtdPtr,
|
||||||
IN EHCI_QTD_ENTITY * QtdPtr
|
IN EHCI_QTD_ENTITY * QtdPtr
|
||||||
)
|
)
|
||||||
|
@ -1467,7 +1578,8 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID LinkQtdsToAltQtd (
|
VOID
|
||||||
|
LinkQtdsToAltQtd (
|
||||||
IN EHCI_QTD_ENTITY * FirstQtdPtr,
|
IN EHCI_QTD_ENTITY * FirstQtdPtr,
|
||||||
IN EHCI_QTD_ENTITY * AltQtdPtr
|
IN EHCI_QTD_ENTITY * AltQtdPtr
|
||||||
)
|
)
|
||||||
|
@ -1560,6 +1672,18 @@ Returns:
|
||||||
QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);
|
QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);
|
||||||
QhPtr->Qh.NextQtdTerminate = FALSE;
|
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 ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1591,9 +1715,23 @@ Returns:
|
||||||
ASSERT (HcDev);
|
ASSERT (HcDev);
|
||||||
ASSERT (QhPtr);
|
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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -1609,7 +1747,7 @@ Returns:
|
||||||
|
|
||||||
Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));
|
DEBUG ((gEHCDebugLevel, "EHCI: WaitForAsyncScheduleEnable TimeOut"));
|
||||||
Status = EFI_TIMEOUT;
|
Status = EFI_TIMEOUT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -1657,7 +1795,22 @@ Returns:
|
||||||
ASSERT (HcDev);
|
ASSERT (HcDev);
|
||||||
ASSERT (QhPtr);
|
ASSERT (QhPtr);
|
||||||
|
|
||||||
if (QhPtr == QhPtr->Next) {
|
|
||||||
|
HcDev->NULLQH->Next = HcDev->NULLQH;
|
||||||
|
HcDev->NULLQH->Prev = HcDev->NULLQH;
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
Status = DisableAsynchronousSchedule (HcDev);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -1667,12 +1820,11 @@ Returns:
|
||||||
|
|
||||||
Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));
|
DEBUG ((gEHCErrorLevel, "EHCI: WaitForAsyncScheduleDisable TimeOut\n"));
|
||||||
Status = EFI_TIMEOUT;
|
Status = EFI_TIMEOUT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2107,21 +2259,20 @@ Returns:
|
||||||
{
|
{
|
||||||
UINTN RemainLen;
|
UINTN RemainLen;
|
||||||
|
|
||||||
RemainLen = DataLen;
|
|
||||||
ASSERT (QtdHwPtr);
|
ASSERT (QtdHwPtr);
|
||||||
|
ASSERT (DataLen <= 5 * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
RemainLen = DataLen;
|
||||||
//
|
//
|
||||||
// Allow buffer address range across 4G.
|
// Allow buffer address range across 4G.
|
||||||
// But EFI_USB_MAX_BULK_BUFFER_NUM = 1, so don't allow
|
// But EFI_USB_MAX_BULK_BUFFER_NUM = 1, so don't allow
|
||||||
// seperate buffer array.
|
// seperate buffer array.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BufferPointer0, ExtBufferPointer0 and Offset
|
// 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->CurrentOffset = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);
|
||||||
QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BufferPointer1 and ExtBufferPointer1
|
// Set BufferPointer1 and ExtBufferPointer1
|
||||||
|
@ -2132,7 +2283,6 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
QtdHwPtr->BufferPointer1 = QtdHwPtr->BufferPointer0 + 1;
|
QtdHwPtr->BufferPointer1 = QtdHwPtr->BufferPointer0 + 1;
|
||||||
QtdHwPtr->ExtBufferPointer1 = (QtdHwPtr->BufferPointer1 == 0) ? (QtdHwPtr->ExtBufferPointer0 + 1) : QtdHwPtr->ExtBufferPointer0;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BufferPointer2 and ExtBufferPointer2
|
// Set BufferPointer2 and ExtBufferPointer2
|
||||||
|
@ -2143,7 +2293,6 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
QtdHwPtr->BufferPointer2 = QtdHwPtr->BufferPointer1 + 1;
|
QtdHwPtr->BufferPointer2 = QtdHwPtr->BufferPointer1 + 1;
|
||||||
QtdHwPtr->ExtBufferPointer2 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer1 + 1) : QtdHwPtr->ExtBufferPointer1;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BufferPointer3 and ExtBufferPointer3
|
// Set BufferPointer3 and ExtBufferPointer3
|
||||||
|
@ -2154,7 +2303,6 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
QtdHwPtr->BufferPointer3 = QtdHwPtr->BufferPointer2 + 1;
|
QtdHwPtr->BufferPointer3 = QtdHwPtr->BufferPointer2 + 1;
|
||||||
QtdHwPtr->ExtBufferPointer3 = (QtdHwPtr->BufferPointer2 == 0) ? (QtdHwPtr->ExtBufferPointer2 + 1) : QtdHwPtr->ExtBufferPointer2;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BufferPointer4 and ExtBufferPointer4
|
// Set BufferPointer4 and ExtBufferPointer4
|
||||||
|
@ -2165,7 +2313,6 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
QtdHwPtr->BufferPointer4 = QtdHwPtr->BufferPointer3 + 1;
|
QtdHwPtr->BufferPointer4 = QtdHwPtr->BufferPointer3 + 1;
|
||||||
QtdHwPtr->ExtBufferPointer4 = (QtdHwPtr->BufferPointer3 == 0) ? (QtdHwPtr->ExtBufferPointer3 + 1) : QtdHwPtr->ExtBufferPointer3;
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return ;
|
return ;
|
||||||
|
@ -2197,6 +2344,7 @@ Returns:
|
||||||
|
|
||||||
QtdStatus = (UINT8) (HwQtdPtr->Status);
|
QtdStatus = (UINT8) (HwQtdPtr->Status);
|
||||||
Value = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);
|
Value = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);
|
||||||
|
//DEBUG ((gEHCErrorLevel, "EHCI: IsQtdStatusActive 0x%X, Address = %x\r\n",HwQtdPtr->Status, HwQtdPtr));
|
||||||
|
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
@ -2408,7 +2556,7 @@ Returns:
|
||||||
DataMap
|
DataMap
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));
|
DEBUG ((gEHCDebugLevel, "EHCI: MapDataBuffer Failed\n"));
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -2578,7 +2726,7 @@ Returns:
|
||||||
|
|
||||||
Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));
|
DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleDisable TimeOut\n"));
|
||||||
Status = EFI_TIMEOUT;
|
Status = EFI_TIMEOUT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -2605,7 +2753,7 @@ Returns:
|
||||||
|
|
||||||
Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));
|
DEBUG ((gEHCErrorLevel, "EHCI: WaitForPeriodicScheduleEnable TimeOut\n"));
|
||||||
Status = EFI_TIMEOUT;
|
Status = EFI_TIMEOUT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -2711,11 +2859,6 @@ Returns:
|
||||||
QhPtr->Qh.FrameTag = 0;
|
QhPtr->Qh.FrameTag = 0;
|
||||||
QhPtr->Qh.BufferPointer3 = 0;
|
QhPtr->Qh.BufferPointer3 = 0;
|
||||||
QhPtr->Qh.BufferPointer4 = 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
|
VOID
|
||||||
|
@ -2829,25 +2972,37 @@ Returns:
|
||||||
QtdHwPtr = &(QtdPtr->Qtd);
|
QtdHwPtr = &(QtdPtr->Qtd);
|
||||||
|
|
||||||
while (NULL != QtdHwPtr) {
|
while (NULL != QtdHwPtr) {
|
||||||
|
|
||||||
if (IsQtdStatusActive (QtdHwPtr)) {
|
if (IsQtdStatusActive (QtdHwPtr)) {
|
||||||
*Result |= EFI_USB_ERR_NOTEXECUTE;
|
*Result |= EFI_USB_ERR_NOTEXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsQtdStatusHalted (QtdHwPtr)) {
|
if (IsQtdStatusHalted (QtdHwPtr)) {
|
||||||
|
|
||||||
|
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_HALTED 0x%X\n", QtdHwPtr->Status));
|
||||||
*Result |= EFI_USB_ERR_STALL;
|
*Result |= EFI_USB_ERR_STALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsQtdStatusBufferError (QtdHwPtr)) {
|
if (IsQtdStatusBufferError (QtdHwPtr)) {
|
||||||
|
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_BUFFER_ERR 0x%X\n", QtdHwPtr->Status));
|
||||||
*Result |= EFI_USB_ERR_BUFFER;
|
*Result |= EFI_USB_ERR_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsQtdStatusBabbleError (QtdHwPtr)) {
|
if (IsQtdStatusBabbleError (QtdHwPtr)) {
|
||||||
|
DEBUG ((gEHCErrorLevel, "EHCI: StatusBufferError 0x%X\n", QtdHwPtr->Status));
|
||||||
*Result |= EFI_USB_ERR_BABBLE;
|
*Result |= EFI_USB_ERR_BABBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsQtdStatusTransactionError (QtdHwPtr)) {
|
if (IsQtdStatusTransactionError (QtdHwPtr)) {
|
||||||
|
|
||||||
|
//
|
||||||
|
//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;
|
*Result |= EFI_USB_ERR_TIMEOUT;
|
||||||
|
DEBUG ((gEHCErrorLevel, "EHCI: QTD_STATUS_TRANSACTION_ERR: 0x%X\n", QtdHwPtr->Status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ActualLenPerQtd = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;
|
ActualLenPerQtd = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;
|
||||||
|
@ -2864,16 +3019,21 @@ Returns:
|
||||||
break;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (QtdPtr->Next != NULL) {
|
||||||
(*ErrQtdPos)++;
|
(*ErrQtdPos)++;
|
||||||
QtdPtr = QtdPtr->Next;
|
QtdPtr = QtdPtr->Next;
|
||||||
QtdHwPtr = &(QtdPtr->Qtd);
|
QtdHwPtr = &(QtdPtr->Qtd);
|
||||||
|
} else {
|
||||||
|
QtdHwPtr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2924,7 +3084,7 @@ Returns:
|
||||||
*ActualLen = 0;
|
*ActualLen = 0;
|
||||||
Finished = FALSE;
|
Finished = FALSE;
|
||||||
|
|
||||||
Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
|
Delay = (TimeOut * STALL_1_MILLI_SECOND / 50);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
*TransferResult = 0;
|
*TransferResult = 0;
|
||||||
|
@ -2951,6 +3111,7 @@ Returns:
|
||||||
|
|
||||||
if (EFI_USB_NOERROR != *TransferResult) {
|
if (EFI_USB_NOERROR != *TransferResult) {
|
||||||
if (0 == Delay) {
|
if (0 == Delay) {
|
||||||
|
DEBUG((gEHCErrorLevel, "EHCI: QTDS TimeOut\n"));
|
||||||
Status = EFI_TIMEOUT;
|
Status = EFI_TIMEOUT;
|
||||||
} else {
|
} else {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
@ -2989,13 +3150,13 @@ Returns:
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
USB2_HC_DEV *HcDev;
|
USB2_HC_DEV *HcDev;
|
||||||
EHCI_ASYNC_REQUEST *AsyncRequestPtr;
|
EHCI_ASYNC_REQUEST *AsyncRequestPtr;
|
||||||
|
EHCI_ASYNC_REQUEST *NextPtr;
|
||||||
EHCI_QTD_HW *QtdHwPtr;
|
EHCI_QTD_HW *QtdHwPtr;
|
||||||
UINTN ErrQtdPos;
|
UINTN ErrQtdPos;
|
||||||
UINTN ActualLen;
|
UINTN ActualLen;
|
||||||
UINT32 TransferResult;
|
UINT32 TransferResult;
|
||||||
UINT8 *ReceiveBuffer;
|
UINT8 *ReceiveBuffer;
|
||||||
UINT8 *ProcessBuffer;
|
UINT8 *ProcessBuffer;
|
||||||
EHCI_ASYNC_REQUEST *NextPtr;
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
QtdHwPtr = NULL;
|
QtdHwPtr = NULL;
|
||||||
|
@ -3032,7 +3193,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);
|
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 (
|
CopyMem (
|
||||||
ProcessBuffer,
|
ProcessBuffer,
|
||||||
ReceiveBuffer,
|
ReceiveBuffer,
|
||||||
|
|
|
@ -485,6 +485,7 @@ UHCIDriverBindingStart (
|
||||||
UINTN FlBaseAddrReg;
|
UINTN FlBaseAddrReg;
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
USB_HC_DEV *HcDev;
|
USB_HC_DEV *HcDev;
|
||||||
|
UINT64 Supports;
|
||||||
|
|
||||||
HcDev = NULL;
|
HcDev = NULL;
|
||||||
|
|
||||||
|
@ -508,12 +509,21 @@ UHCIDriverBindingStart (
|
||||||
//
|
//
|
||||||
// Enable the USB Host Controller
|
// Enable the USB Host Controller
|
||||||
//
|
//
|
||||||
|
Status = PciIo->Attributes (
|
||||||
|
PciIo,
|
||||||
|
EfiPciIoAttributeOperationSupported,
|
||||||
|
0,
|
||||||
|
&Supports
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
Status = PciIo->Attributes (
|
Status = PciIo->Attributes (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoAttributeOperationEnable,
|
EfiPciIoAttributeOperationEnable,
|
||||||
EFI_PCI_DEVICE_ENABLE,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
gBS->CloseProtocol (
|
gBS->CloseProtocol (
|
||||||
Controller,
|
Controller,
|
||||||
|
@ -777,6 +787,8 @@ UnInstallUHCInterface (
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
USB_HC_DEV *HcDev;
|
USB_HC_DEV *HcDev;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 Supports;
|
||||||
|
|
||||||
HcDev = USB_HC_DEV_FROM_THIS (This);
|
HcDev = USB_HC_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
@ -823,12 +835,21 @@ UnInstallUHCInterface (
|
||||||
//
|
//
|
||||||
// Disable the USB Host Controller
|
// Disable the USB Host Controller
|
||||||
//
|
//
|
||||||
HcDev->PciIo->Attributes (
|
Status = HcDev->PciIo->Attributes (
|
||||||
|
HcDev->PciIo,
|
||||||
|
EfiPciIoAttributeOperationSupported,
|
||||||
|
0,
|
||||||
|
&Supports
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
|
Status = HcDev->PciIo->Attributes (
|
||||||
HcDev->PciIo,
|
HcDev->PciIo,
|
||||||
EfiPciIoAttributeOperationDisable,
|
EfiPciIoAttributeOperationDisable,
|
||||||
EFI_PCI_DEVICE_ENABLE,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
gBS->FreePool (HcDev);
|
gBS->FreePool (HcDev);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ Abstract:
|
||||||
|
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
|
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTDebugLevel = EFI_D_INFO;
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 gBOTErrorLevel = EFI_D_INFO;
|
||||||
//
|
//
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
//
|
//
|
||||||
|
@ -85,7 +87,7 @@ STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BotDataPhase (
|
BotDataPhase (
|
||||||
IN USB_BOT_DEVICE *UsbBotDev,
|
IN USB_BOT_DEVICE *UsbBotDev,
|
||||||
IN UINT32 *DataSize,
|
IN UINTN *DataSize,
|
||||||
IN OUT VOID *DataBuffer,
|
IN OUT VOID *DataBuffer,
|
||||||
IN EFI_USB_DATA_DIRECTION Direction,
|
IN EFI_USB_DATA_DIRECTION Direction,
|
||||||
IN UINT16 Timeout
|
IN UINT16 Timeout
|
||||||
|
@ -95,10 +97,9 @@ STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BotStatusPhase (
|
BotStatusPhase (
|
||||||
IN USB_BOT_DEVICE *UsbBotDev,
|
IN USB_BOT_DEVICE *UsbBotDev,
|
||||||
OUT UINT8 *TransferStatus,
|
OUT UINT32 *DataResidue,
|
||||||
IN UINT16 Timeout
|
IN UINT16 Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// USB Atapi protocol prototype
|
// USB Atapi protocol prototype
|
||||||
//
|
//
|
||||||
|
@ -193,7 +194,7 @@ BotDriverBindingSupported (
|
||||||
//
|
//
|
||||||
// Check if it is a BOT type Mass Storage Device
|
// Check if it is a BOT type Mass Storage Device
|
||||||
//
|
//
|
||||||
if ((InterfaceDescriptor.InterfaceClass != 0x08) ||
|
if ((InterfaceDescriptor.InterfaceClass != MASS_STORAGE_CLASS) ||
|
||||||
(InterfaceDescriptor.InterfaceProtocol != BOT)) {
|
(InterfaceDescriptor.InterfaceProtocol != BOT)) {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -513,6 +514,38 @@ BotDriverBindingStop (
|
||||||
return Status;
|
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
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BotRecoveryReset (
|
BotRecoveryReset (
|
||||||
|
@ -534,13 +567,8 @@ Returns:
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 Result;
|
|
||||||
EFI_USB_DEVICE_REQUEST Request;
|
EFI_USB_DEVICE_REQUEST Request;
|
||||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
UINT32 Result;
|
||||||
UINT8 EndpointAddr;
|
|
||||||
|
|
||||||
UsbIo = UsbBotDev->UsbIo;
|
|
||||||
|
|
||||||
BotReportStatusCode (
|
BotReportStatusCode (
|
||||||
UsbBotDev->DevicePath,
|
UsbBotDev->DevicePath,
|
||||||
EFI_PROGRESS_CODE,
|
EFI_PROGRESS_CODE,
|
||||||
|
@ -555,8 +583,8 @@ Returns:
|
||||||
Request.RequestType = 0x21;
|
Request.RequestType = 0x21;
|
||||||
Request.Request = 0xFF;
|
Request.Request = 0xFF;
|
||||||
|
|
||||||
Status = UsbIo->UsbControlTransfer (
|
Status = UsbBotDev->UsbIo->UsbControlTransfer (
|
||||||
UsbIo,
|
UsbBotDev->UsbIo,
|
||||||
&Request,
|
&Request,
|
||||||
EfiUsbNoData,
|
EfiUsbNoData,
|
||||||
TIMEOUT_VALUE,
|
TIMEOUT_VALUE,
|
||||||
|
@ -567,31 +595,12 @@ Returns:
|
||||||
|
|
||||||
gBS->Stall (100 * 1000);
|
gBS->Stall (100 * 1000);
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
ClearBulkInPipe (UsbBotDev);
|
||||||
//
|
ClearBulkOutPipe (UsbBotDev);
|
||||||
// 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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bot Protocol Implementation
|
// Bot Protocol Implementation
|
||||||
//
|
//
|
||||||
|
@ -639,7 +648,17 @@ BotCommandPhase (
|
||||||
cbw.dCBWSignature = CBWSIG;
|
cbw.dCBWSignature = CBWSIG;
|
||||||
cbw.dCBWTag = 0x01;
|
cbw.dCBWTag = 0x01;
|
||||||
cbw.dCBWDataTransferLength = DataTransferLength;
|
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;
|
cbw.bCBWCBLength = CommandSize;
|
||||||
|
|
||||||
CopyMem (cbw.CBWCB, Command, CommandSize);
|
CopyMem (cbw.CBWCB, Command, CommandSize);
|
||||||
|
@ -648,28 +667,20 @@ BotCommandPhase (
|
||||||
|
|
||||||
Status = UsbIo->UsbBulkTransfer (
|
Status = UsbIo->UsbBulkTransfer (
|
||||||
UsbIo,
|
UsbIo,
|
||||||
(UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress,
|
UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,
|
||||||
&cbw,
|
&cbw,
|
||||||
&DataSize,
|
&DataSize,
|
||||||
Timeout,
|
Timeout,
|
||||||
&Result
|
&Result
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
return Status;
|
||||||
//
|
|
||||||
// Command phase fail, we need to recovery reset this device
|
|
||||||
//
|
|
||||||
BotRecoveryReset (UsbBotDev);
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BotDataPhase (
|
BotDataPhase (
|
||||||
IN USB_BOT_DEVICE *UsbBotDev,
|
IN USB_BOT_DEVICE *UsbBotDev,
|
||||||
IN UINT32 *DataSize,
|
IN UINTN *DataSize,
|
||||||
IN OUT VOID *DataBuffer,
|
IN OUT VOID *DataBuffer,
|
||||||
IN EFI_USB_DATA_DIRECTION Direction,
|
IN EFI_USB_DATA_DIRECTION Direction,
|
||||||
IN UINT16 Timeout
|
IN UINT16 Timeout
|
||||||
|
@ -695,124 +706,51 @@ BotDataPhase (
|
||||||
UINT32 Result;
|
UINT32 Result;
|
||||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||||
UINT8 EndpointAddr;
|
UINT8 EndpointAddr;
|
||||||
UINTN Remain;
|
|
||||||
UINTN Increment;
|
|
||||||
UINT32 MaxPacketLen;
|
|
||||||
UINT8 *BufferPtr;
|
UINT8 *BufferPtr;
|
||||||
UINTN TransferredSize;
|
|
||||||
UINTN RetryTimes;
|
|
||||||
UINTN MaxRetry;
|
|
||||||
UINTN BlockSize;
|
|
||||||
UINTN PackageNum;
|
|
||||||
|
|
||||||
UsbIo = UsbBotDev->UsbIo;
|
UsbIo = UsbBotDev->UsbIo;
|
||||||
Remain = *DataSize;
|
|
||||||
BufferPtr = (UINT8 *) DataBuffer;
|
BufferPtr = (UINT8 *) DataBuffer;
|
||||||
TransferredSize = 0;
|
|
||||||
MaxRetry = 10;
|
|
||||||
PackageNum = 128;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// retrieve the the max packet length of the given endpoint
|
// retrieve the the max packet length of the given endpoint
|
||||||
//
|
//
|
||||||
if (Direction == EfiUsbDataIn) {
|
if (Direction == EfiUsbDataIn) {
|
||||||
MaxPacketLen = (UsbBotDev->BulkInEndpointDescriptor)->MaxPacketSize;
|
EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;
|
||||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
|
||||||
} else {
|
} 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 (
|
Status = UsbIo->UsbBulkTransfer (
|
||||||
UsbIo,
|
UsbIo,
|
||||||
EndpointAddr,
|
EndpointAddr,
|
||||||
BufferPtr,
|
BufferPtr,
|
||||||
&Increment,
|
DataSize,
|
||||||
Timeout,
|
(UINT16)(Timeout),
|
||||||
&Result
|
&Result
|
||||||
);
|
);
|
||||||
|
|
||||||
TransferredSize += Increment;
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
RetryTimes--;
|
|
||||||
if ((RetryTimes == 0) || ((Result & EFI_USB_ERR_TIMEOUT) == 0)) {
|
|
||||||
goto ErrorExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||||
//
|
if (Direction == EfiUsbDataIn) {
|
||||||
// just endpoint stall happens
|
DEBUG((gBOTErrorLevel, "BOT: Data IN Stall, ClearBulkInPipe\n"));
|
||||||
//
|
ClearBulkInPipe (UsbBotDev);
|
||||||
UsbClearEndpointHalt (
|
} else {
|
||||||
UsbIo,
|
DEBUG((gBOTErrorLevel, "BOT: Data OUT Stall, ClearBulkInPipe\n"));
|
||||||
EndpointAddr,
|
ClearBulkOutPipe (UsbBotDev);
|
||||||
&Result
|
}
|
||||||
);
|
}
|
||||||
|
// BotRecoveryReset (UsbBotDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
*DataSize = (UINT32) TransferredSize;
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BotStatusPhase (
|
BotStatusPhase (
|
||||||
IN USB_BOT_DEVICE *UsbBotDev,
|
IN USB_BOT_DEVICE *UsbBotDev,
|
||||||
OUT UINT8 *TransferStatus,
|
OUT UINT32 *DataResidue,
|
||||||
IN UINT16 Timeout
|
IN UINT16 Timeout
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
@ -822,7 +760,6 @@ BotStatusPhase (
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
UsbBotDev - USB_BOT_DEVICE pointer
|
UsbBotDev - USB_BOT_DEVICE pointer
|
||||||
TransferStatus - TransferStatus
|
|
||||||
Timeout - Time out value in milliseconds
|
Timeout - Time out value in milliseconds
|
||||||
Return Value:
|
Return Value:
|
||||||
EFI_SUCCESS
|
EFI_SUCCESS
|
||||||
|
@ -832,22 +769,21 @@ BotStatusPhase (
|
||||||
{
|
{
|
||||||
CSW csw;
|
CSW csw;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 Result;
|
|
||||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||||
UINT8 EndpointAddr;
|
UINT8 EndpointAddr;
|
||||||
UINTN DataSize;
|
UINTN DataSize;
|
||||||
|
UINT32 Result;
|
||||||
|
UINT8 Index;
|
||||||
|
|
||||||
UsbIo = UsbBotDev->UsbIo;
|
UsbIo = UsbBotDev->UsbIo;
|
||||||
|
EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;
|
||||||
|
|
||||||
|
|
||||||
|
for (Index = 0; Index < 3; Index ++) {
|
||||||
ZeroMem (&csw, sizeof (CSW));
|
ZeroMem (&csw, sizeof (CSW));
|
||||||
|
|
||||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
|
||||||
|
|
||||||
DataSize = sizeof (CSW);
|
DataSize = sizeof (CSW);
|
||||||
|
Result = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// Get the status field from bulk transfer
|
|
||||||
//
|
|
||||||
Status = UsbIo->UsbBulkTransfer (
|
Status = UsbIo->UsbBulkTransfer (
|
||||||
UsbIo,
|
UsbIo,
|
||||||
EndpointAddr,
|
EndpointAddr,
|
||||||
|
@ -858,50 +794,36 @@ BotStatusPhase (
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
||||||
//
|
DEBUG((gBOTDebugLevel, "BOT: CSW Stall, ClearBulkInPipe\n"));
|
||||||
// just endpoint stall happens
|
ClearBulkInPipe (UsbBotDev);
|
||||||
//
|
continue;
|
||||||
UsbClearEndpointHalt (
|
|
||||||
UsbIo,
|
|
||||||
EndpointAddr,
|
|
||||||
&Result
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMem (&csw, sizeof (CSW));
|
|
||||||
|
|
||||||
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
|
|
||||||
|
|
||||||
DataSize = sizeof (CSW);
|
|
||||||
Status = UsbIo->UsbBulkTransfer (
|
|
||||||
UsbIo,
|
|
||||||
EndpointAddr,
|
|
||||||
&csw,
|
|
||||||
&DataSize,
|
|
||||||
Timeout,
|
|
||||||
&Result
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
|
|
||||||
UsbClearEndpointHalt (
|
|
||||||
UsbIo,
|
|
||||||
EndpointAddr,
|
|
||||||
&Result
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csw.dCSWSignature == CSWSIG) {
|
if (csw.dCSWSignature == CSWSIG) {
|
||||||
*TransferStatus = csw.bCSWStatus;
|
if (csw.bCSWStatus == 0 || csw.bCSWStatus == 0x01) {
|
||||||
} else {
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Index == 3) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Usb Atapi Protocol implementation
|
// Usb Atapi Protocol implementation
|
||||||
//
|
//
|
||||||
|
@ -938,18 +860,19 @@ BotAtapiCommand (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_STATUS BotDataStatus;
|
EFI_STATUS BotDataStatus;
|
||||||
UINT8 TransferStatus;
|
|
||||||
USB_BOT_DEVICE *UsbBotDev;
|
USB_BOT_DEVICE *UsbBotDev;
|
||||||
UINT32 BufferSize;
|
UINTN BufferSize;
|
||||||
|
UINT8 Index;
|
||||||
BotDataStatus = EFI_SUCCESS;
|
UINT32 DataResidue;
|
||||||
TransferStatus = 0;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the context
|
// Get the context
|
||||||
//
|
//
|
||||||
UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);
|
UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);
|
||||||
|
BotDataStatus = EFI_SUCCESS;
|
||||||
|
BufferSize = 0;
|
||||||
|
|
||||||
|
for (Index = 0; Index < 3; Index ++) {
|
||||||
//
|
//
|
||||||
// First send ATAPI command through Bot
|
// First send ATAPI command through Bot
|
||||||
//
|
//
|
||||||
|
@ -959,11 +882,12 @@ BotAtapiCommand (
|
||||||
CommandSize,
|
CommandSize,
|
||||||
BufferLength,
|
BufferLength,
|
||||||
Direction,
|
Direction,
|
||||||
TimeOutInMilliSeconds
|
10 * 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
DEBUG((gBOTErrorLevel, "BotCommandPhase Fail\n"));
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Send/Get Data if there is a Data Stage
|
// Send/Get Data if there is a Data Stage
|
||||||
|
@ -982,37 +906,36 @@ BotAtapiCommand (
|
||||||
(UINT16) (TimeOutInMilliSeconds)
|
(UINT16) (TimeOutInMilliSeconds)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (EFI_ERROR (BotDataStatus)) {
|
||||||
|
DEBUG((gBOTErrorLevel, "BotDataPhase Fail\n"));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EfiUsbNoData:
|
case EfiUsbNoData:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataResidue = 0;
|
||||||
//
|
//
|
||||||
// Status Phase
|
// Status Phase
|
||||||
//
|
//
|
||||||
Status = BotStatusPhase (
|
Status = BotStatusPhase (
|
||||||
UsbBotDev,
|
UsbBotDev,
|
||||||
&TransferStatus,
|
&DataResidue,
|
||||||
TimeOutInMilliSeconds
|
10 * 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
DEBUG((gBOTErrorLevel, "BotStatusPhase Fail\n"));
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TransferStatus == 0x02) {
|
if (!EFI_ERROR (BotDataStatus)) {
|
||||||
//
|
break;
|
||||||
// Phase error
|
|
||||||
//
|
|
||||||
BotRecoveryReset (UsbBotDev);
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TransferStatus == 0x01) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return BotDataStatus;
|
return BotDataStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ Abstract:
|
||||||
|
|
||||||
|
|
||||||
#include <IndustryStandard/Usb.h>
|
#include <IndustryStandard/Usb.h>
|
||||||
|
extern UINT32 gBOTDebugLevel;
|
||||||
|
extern UINT32 gBOTErrorLevel;
|
||||||
|
#define MASS_STORAGE_CLASS 0x08
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
//
|
//
|
||||||
|
|
|
@ -396,7 +396,7 @@ USBFloppyReset (
|
||||||
//
|
//
|
||||||
// directly calling EFI_USB_ATAPI_PROTOCOL.Reset() to implement reset.
|
// directly calling EFI_USB_ATAPI_PROTOCOL.Reset() to implement reset.
|
||||||
//
|
//
|
||||||
Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, TRUE);
|
Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, ExtendedVerification);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -442,12 +442,9 @@ USBFloppyReadBlocks (
|
||||||
UINTN BlockSize;
|
UINTN BlockSize;
|
||||||
UINTN NumberOfBlocks;
|
UINTN NumberOfBlocks;
|
||||||
BOOLEAN MediaChange;
|
BOOLEAN MediaChange;
|
||||||
EFI_TPL OldTpl;
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
MediaChange = FALSE;
|
MediaChange = FALSE;
|
||||||
|
|
||||||
UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);
|
UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -473,14 +470,12 @@ USBFloppyReadBlocks (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MediaChange) {
|
if (MediaChange) {
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
gBS->ReinstallProtocolInterface (
|
gBS->ReinstallProtocolInterface (
|
||||||
UsbFloppyDevice->Handle,
|
UsbFloppyDevice->Handle,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
&UsbFloppyDevice->BlkIo,
|
&UsbFloppyDevice->BlkIo,
|
||||||
&UsbFloppyDevice->BlkIo
|
&UsbFloppyDevice->BlkIo
|
||||||
);
|
);
|
||||||
gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Media = UsbFloppyDevice->BlkIo.Media;
|
Media = UsbFloppyDevice->BlkIo.Media;
|
||||||
|
@ -517,33 +512,31 @@ USBFloppyReadBlocks (
|
||||||
goto Done;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LBA += 1;
|
|
||||||
NumberOfBlocks -= 1;
|
|
||||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize;
|
|
||||||
|
|
||||||
if (NumberOfBlocks == 0) {
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||||
|
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
|
||||||
|
} else {
|
||||||
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
This->Reset (This, TRUE);
|
This->Reset (This, TRUE);
|
||||||
Status = EFI_DEVICE_ERROR;
|
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:
|
Done:
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,9 +584,7 @@ USBFloppyWriteBlocks (
|
||||||
UINTN BlockSize;
|
UINTN BlockSize;
|
||||||
UINTN NumberOfBlocks;
|
UINTN NumberOfBlocks;
|
||||||
BOOLEAN MediaChange;
|
BOOLEAN MediaChange;
|
||||||
EFI_TPL OldTpl;
|
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
MediaChange = FALSE;
|
MediaChange = FALSE;
|
||||||
|
|
||||||
|
@ -622,14 +613,12 @@ USBFloppyWriteBlocks (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MediaChange) {
|
if (MediaChange) {
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
gBS->ReinstallProtocolInterface (
|
gBS->ReinstallProtocolInterface (
|
||||||
UsbFloppyDevice->Handle,
|
UsbFloppyDevice->Handle,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
&UsbFloppyDevice->BlkIo,
|
&UsbFloppyDevice->BlkIo,
|
||||||
&UsbFloppyDevice->BlkIo
|
&UsbFloppyDevice->BlkIo
|
||||||
);
|
);
|
||||||
gBS->RaiseTPL (EFI_TPL_NOTIFY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Media = UsbFloppyDevice->BlkIo.Media;
|
Media = UsbFloppyDevice->BlkIo.Media;
|
||||||
|
@ -671,32 +660,32 @@ USBFloppyWriteBlocks (
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
while (NumberOfBlocks > 0) {
|
||||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, 1);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
This->Reset (This, TRUE);
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
LBA += 1;
|
|
||||||
NumberOfBlocks -= 1;
|
|
||||||
Buffer = (UINT8 *) Buffer + This->Media->BlockSize;
|
|
||||||
|
|
||||||
if (NumberOfBlocks == 0) {
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (NumberOfBlocks > BLOCK_UNIT) {
|
||||||
|
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
|
||||||
|
} else {
|
||||||
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
This->Reset (This, TRUE);
|
This->Reset (This, TRUE);
|
||||||
Status = EFI_DEVICE_ERROR;
|
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:
|
Done:
|
||||||
gBS->RestoreTPL (OldTpl);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ Revision History
|
||||||
#define USBFLOPPY2 2 // for those that use ReadFormatCapacity(0x23) command to retrieve media capacity
|
#define USBFLOPPY2 2 // for those that use ReadFormatCapacity(0x23) command to retrieve media capacity
|
||||||
#define USBCDROM 3
|
#define USBCDROM 3
|
||||||
|
|
||||||
|
#define BLOCK_UNIT 128
|
||||||
|
|
||||||
#define USB_FLOPPY_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'f', 'l', 'p')
|
#define USB_FLOPPY_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'f', 'l', 'p')
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -50,7 +52,6 @@ typedef struct {
|
||||||
REQUEST_SENSE_DATA *SenseData;
|
REQUEST_SENSE_DATA *SenseData;
|
||||||
UINT8 SenseDataNumber;
|
UINT8 SenseDataNumber;
|
||||||
UINT8 DeviceType;
|
UINT8 DeviceType;
|
||||||
|
|
||||||
} USB_FLOPPY_DEV;
|
} USB_FLOPPY_DEV;
|
||||||
|
|
||||||
#define USB_FLOPPY_DEV_FROM_THIS(a) \
|
#define USB_FLOPPY_DEV_FROM_THIS(a) \
|
||||||
|
|
|
@ -30,7 +30,7 @@ Revision History
|
||||||
//
|
//
|
||||||
// timeout unit is in millisecond.
|
// timeout unit is in millisecond.
|
||||||
//
|
//
|
||||||
#define USBFLPTIMEOUT 2000
|
#define USBFLPTIMEOUT 1000
|
||||||
#define STALL_1_MILLI_SECOND 1000
|
#define STALL_1_MILLI_SECOND 1000
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -310,7 +310,7 @@ USBFloppyRead10 (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT16 TimeOut;
|
UINT16 TimeOut;
|
||||||
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
||||||
UINTN SenseCounts;
|
UINT8 Index;
|
||||||
|
|
||||||
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
||||||
|
|
||||||
|
@ -333,11 +333,13 @@ USBFloppyRead10 (
|
||||||
} else {
|
} else {
|
||||||
SectorCount = MaxBlock;
|
SectorCount = MaxBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < 3; Index ++) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// fill the Packet data structure
|
// fill the Packet data structure
|
||||||
//
|
//
|
||||||
Read10Packet->opcode = READ_10;
|
Read10Packet->opcode = READ_10;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Lba0 ~ Lba3 specify the start logical block address of the data transfer.
|
// Lba0 ~ Lba3 specify the start logical block address of the data transfer.
|
||||||
// Lba0 is MSB, Lba3 is LSB
|
// Lba0 is MSB, Lba3 is LSB
|
||||||
|
@ -358,6 +360,7 @@ USBFloppyRead10 (
|
||||||
|
|
||||||
TimeOut = (UINT16) (SectorCount * USBFLPTIMEOUT);
|
TimeOut = (UINT16) (SectorCount * USBFLPTIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
Status = USBFloppyPacketCommand (
|
Status = USBFloppyPacketCommand (
|
||||||
UsbFloppyDevice,
|
UsbFloppyDevice,
|
||||||
&Packet,
|
&Packet,
|
||||||
|
@ -367,43 +370,14 @@ USBFloppyRead10 (
|
||||||
EfiUsbDataIn,
|
EfiUsbDataIn,
|
||||||
TimeOut
|
TimeOut
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
if (IsLogicalUnitCommunicationOverRun (
|
break;
|
||||||
UsbFloppyDevice->SenseData,
|
}
|
||||||
SenseCounts
|
|
||||||
)) {
|
|
||||||
Lba32 = (UINT32) Lba;
|
|
||||||
ptrBuffer = Buffer;
|
|
||||||
BlocksRemaining = (UINT16) NumberOfBlocks;
|
|
||||||
MaxBlock = (UINT16) (MaxBlock / 4);
|
|
||||||
if (MaxBlock < 1) {
|
|
||||||
MaxBlock = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
if (Index == 3) {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// retry read10 command
|
|
||||||
//
|
|
||||||
Status = USBFloppyPacketCommand (
|
|
||||||
UsbFloppyDevice,
|
|
||||||
&Packet,
|
|
||||||
sizeof (ATAPI_PACKET_COMMAND),
|
|
||||||
(VOID *) ptrBuffer,
|
|
||||||
ByteCount,
|
|
||||||
EfiUsbDataIn,
|
|
||||||
TimeOut
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Lba32 += SectorCount;
|
Lba32 += SectorCount;
|
||||||
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
||||||
|
@ -775,7 +749,7 @@ USBFloppyWrite10 (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT16 TimeOut;
|
UINT16 TimeOut;
|
||||||
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;
|
||||||
UINTN SenseCounts;
|
UINT8 Index;
|
||||||
|
|
||||||
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;
|
||||||
|
|
||||||
|
@ -795,12 +769,12 @@ USBFloppyWrite10 (
|
||||||
while (BlocksRemaining > 0) {
|
while (BlocksRemaining > 0) {
|
||||||
|
|
||||||
if (BlocksRemaining <= MaxBlock) {
|
if (BlocksRemaining <= MaxBlock) {
|
||||||
|
|
||||||
SectorCount = BlocksRemaining;
|
SectorCount = BlocksRemaining;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
SectorCount = MaxBlock;
|
SectorCount = MaxBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < 3; Index ++) {
|
||||||
//
|
//
|
||||||
// fill the Packet data structure
|
// fill the Packet data structure
|
||||||
//
|
//
|
||||||
|
@ -836,40 +810,14 @@ USBFloppyWrite10 (
|
||||||
EfiUsbDataOut,
|
EfiUsbDataOut,
|
||||||
TimeOut
|
TimeOut
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
Status = UsbFloppyRequestSense (UsbFloppyDevice, &SenseCounts);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
if (IsLogicalUnitCommunicationOverRun (
|
break;
|
||||||
UsbFloppyDevice->SenseData,
|
}
|
||||||
SenseCounts
|
|
||||||
)) {
|
|
||||||
Lba32 = (UINT32) Lba;
|
|
||||||
ptrBuffer = Buffer;
|
|
||||||
BlocksRemaining = (UINT16) NumberOfBlocks;
|
|
||||||
MaxBlock = (UINT16) (MaxBlock / 4);
|
|
||||||
if (MaxBlock < 1) {
|
|
||||||
MaxBlock = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
if (Index == 3) {
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// retry write10 command
|
|
||||||
//
|
|
||||||
Status = USBFloppyPacketCommand (
|
|
||||||
UsbFloppyDevice,
|
|
||||||
&Packet,
|
|
||||||
sizeof (ATAPI_PACKET_COMMAND),
|
|
||||||
(VOID *) ptrBuffer,
|
|
||||||
ByteCount,
|
|
||||||
EfiUsbDataOut,
|
|
||||||
TimeOut
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Lba32 += SectorCount;
|
Lba32 += SectorCount;
|
||||||
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
|
||||||
|
@ -910,11 +858,10 @@ UsbFloppyDetectMedia (
|
||||||
UINTN RetryTimes;
|
UINTN RetryTimes;
|
||||||
UINTN MaximumRetryTimes;
|
UINTN MaximumRetryTimes;
|
||||||
BOOLEAN NeedRetry;
|
BOOLEAN NeedRetry;
|
||||||
|
BOOLEAN NeedReadCapacity;
|
||||||
//
|
//
|
||||||
// a flag used to determine whether need to perform Read Capacity command.
|
// a flag used to determine whether need to perform Read Capacity command.
|
||||||
//
|
//
|
||||||
BOOLEAN NeedReadCapacity;
|
|
||||||
|
|
||||||
REQUEST_SENSE_DATA *SensePtr;
|
REQUEST_SENSE_DATA *SensePtr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue