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:
qhuang8 2007-01-26 04:08:57 +00:00
parent 01bf334d2c
commit 4d1fe68e1c
16 changed files with 1998 additions and 1893 deletions

View File

@ -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));
}
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}

View File

@ -198,6 +198,8 @@ Returns:
);
}
VOID
ClearLegacySupport (
IN USB2_HC_DEV *HcDev

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -22,6 +22,9 @@ Abstract:
#include <IndustryStandard/Usb.h>
extern UINT32 gBOTDebugLevel;
extern UINT32 gBOTErrorLevel;
#define MASS_STORAGE_CLASS 0x08
#pragma pack(1)
//

View File

@ -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;
}

View File

@ -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) \

View File

@ -30,7 +30,7 @@ Revision History
//
// timeout unit is in millisecond.
//
#define USBFLPTIMEOUT 2000
#define USBFLPTIMEOUT 1000
#define STALL_1_MILLI_SECOND 1000
//

View File

@ -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;