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" #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));
} }
} }

View File

@ -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
@ -375,10 +376,19 @@ EhciDriverBindingStart (
// //
Status = PciIo->Attributes ( Status = PciIo->Attributes (
PciIo, PciIo,
EfiPciIoAttributeOperationEnable, EfiPciIoAttributeOperationSupported,
EFI_PCI_DEVICE_ENABLE, 0,
NULL &Supports
); );
if (!EFI_ERROR (Status)) {
Supports &= EFI_PCI_DEVICE_ENABLE;
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
Supports,
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
// //
@ -673,10 +695,19 @@ EhciDriverBindingStop (
// //
Status = HcDev->PciIo->Attributes ( Status = HcDev->PciIo->Attributes (
HcDev->PciIo, HcDev->PciIo,
EfiPciIoAttributeOperationDisable, EfiPciIoAttributeOperationSupported,
EFI_PCI_DEVICE_ENABLE, 0,
NULL &Supports
); );
if (!EFI_ERROR (Status)) {
Supports &= EFI_PCI_DEVICE_ENABLE;
Status = HcDev->PciIo->Attributes (
HcDev->PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
goto exit; goto exit;

View File

@ -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;
@ -390,8 +395,9 @@ typedef struct _USB2_HC_DEV {
EFI_EVENT AsyncRequestEvent; EFI_EVENT AsyncRequestEvent;
EFI_UNICODE_STRING_TABLE *ControllerNameTable; EFI_UNICODE_STRING_TABLE *ControllerNameTable;
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

View File

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

View File

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

View File

@ -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;
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE; if (EFI_USB_SPEED_HIGH != DeviceSpeed) {
(*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);
} }
// DataToggle ^= 1;
// 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;
}
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,23 +1795,37 @@ Returns:
ASSERT (HcDev); ASSERT (HcDev);
ASSERT (QhPtr); ASSERT (QhPtr);
if (QhPtr == QhPtr->Next) {
Status = DisableAsynchronousSchedule (HcDev); HcDev->NULLQH->Next = HcDev->NULLQH;
if (EFI_ERROR (Status)) { HcDev->NULLQH->Prev = HcDev->NULLQH;
Status = EFI_DEVICE_ERROR;
goto exit;
}
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: 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)) {
*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; 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;
} }
(*ErrQtdPos)++; if (QtdPtr->Next != NULL) {
QtdPtr = QtdPtr->Next; (*ErrQtdPos)++;
QtdHwPtr = &(QtdPtr->Qtd); QtdPtr = QtdPtr->Next;
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,

View File

@ -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;
@ -510,10 +511,19 @@ UHCIDriverBindingStart (
// //
Status = PciIo->Attributes ( Status = PciIo->Attributes (
PciIo, PciIo,
EfiPciIoAttributeOperationEnable, EfiPciIoAttributeOperationSupported,
EFI_PCI_DEVICE_ENABLE, 0,
NULL &Supports
); );
if (!EFI_ERROR (Status)) {
Supports &= EFI_PCI_DEVICE_ENABLE;
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
Supports,
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, HcDev->PciIo,
EfiPciIoAttributeOperationDisable, EfiPciIoAttributeOperationSupported,
EFI_PCI_DEVICE_ENABLE, 0,
NULL &Supports
); );
if (!EFI_ERROR (Status)) {
Supports &= EFI_PCI_DEVICE_ENABLE;
Status = HcDev->PciIo->Attributes (
HcDev->PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
}
gBS->FreePool (HcDev); gBS->FreePool (HcDev);

View File

@ -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
@ -94,11 +96,10 @@ BotDataPhase (
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
); );
// //
// 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,43 +583,24 @@ 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,
NULL, NULL,
0, 0,
&Result &Result
); );
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,125 +706,52 @@ 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 ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
if ((RetryTimes == 0) || ((Result & EFI_USB_ERR_TIMEOUT) == 0)) { if (Direction == EfiUsbDataIn) {
goto ErrorExit; 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; 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,47 +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;
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)); ZeroMem (&csw, sizeof (CSW));
DataSize = sizeof (CSW);
Result = 0;
EndpointAddr = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;
DataSize = sizeof (CSW);
Status = UsbIo->UsbBulkTransfer ( Status = UsbIo->UsbBulkTransfer (
UsbIo, UsbIo,
EndpointAddr, EndpointAddr,
@ -883,25 +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) {
UsbClearEndpointHalt ( DEBUG((gBOTDebugLevel, "BOT: CSW Stall, ClearBulkInPipe\n"));
UsbIo, ClearBulkInPipe (UsbBotDev);
EndpointAddr, continue;
&Result }
); }
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) { if (Index == 3) {
*TransferStatus = csw.bCSWStatus;
} else {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// //
// Usb Atapi Protocol implementation // Usb Atapi Protocol implementation
// //
@ -938,81 +860,82 @@ 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
//
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) {
// //
// Phase error // First send ATAPI command through Bot
// //
BotRecoveryReset (UsbBotDev); Status = BotCommandPhase (
return EFI_DEVICE_ERROR; UsbBotDev,
} Command,
CommandSize,
BufferLength,
Direction,
10 * 1000
);
if (TransferStatus == 0x01) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; 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; return BotDataStatus;
} }

View File

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

View File

@ -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 (NumberOfBlocks > BLOCK_UNIT) {
if (EFI_ERROR (Status)) { Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
This->Reset (This, TRUE); } else {
Status = EFI_DEVICE_ERROR; Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);
goto Done;
} }
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)) { if (EFI_ERROR (Status)) {
This->Reset (This, TRUE); This->Reset (This, TRUE);
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
} }
}
Done: if (NumberOfBlocks > BLOCK_UNIT) {
gBS->RestoreTPL (OldTpl); 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; 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)) { if (NumberOfBlocks > BLOCK_UNIT) {
This->Reset (This, TRUE); Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);
Status = EFI_DEVICE_ERROR; } else {
goto Done; 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)) { 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;
} }

View File

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

View File

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

View File

@ -272,10 +272,10 @@ USBFloppyInquiry (
EFI_STATUS EFI_STATUS
USBFloppyRead10 ( USBFloppyRead10 (
IN USB_FLOPPY_DEV *UsbFloppyDevice, IN USB_FLOPPY_DEV *UsbFloppyDevice,
IN VOID *Buffer, IN VOID *Buffer,
IN EFI_LBA Lba, IN EFI_LBA Lba,
IN UINTN NumberOfBlocks IN UINTN NumberOfBlocks
) )
/*++ /*++
@ -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,78 +333,52 @@ USBFloppyRead10 (
} else { } else {
SectorCount = MaxBlock; SectorCount = MaxBlock;
} }
//
// fill the Packet data structure
//
Read10Packet->opcode = READ_10;
// for (Index = 0; Index < 3; Index ++) {
// 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)) {
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 ( Status = USBFloppyPacketCommand (
UsbFloppyDevice, UsbFloppyDevice,
&Packet, &Packet,
sizeof (ATAPI_PACKET_COMMAND), sizeof (ATAPI_PACKET_COMMAND),
(VOID *) ptrBuffer, (VOID *) ptrBuffer,
ByteCount, ByteCount,
EfiUsbDataIn, EfiUsbDataIn,
TimeOut TimeOut
); );
if (EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; break;
} }
} }
if (Index == 3) {
return EFI_DEVICE_ERROR;
}
Lba32 += SectorCount; Lba32 += SectorCount;
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize; ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount); BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
@ -737,10 +711,10 @@ UsbFloppyTestUnitReady (
EFI_STATUS EFI_STATUS
USBFloppyWrite10 ( USBFloppyWrite10 (
IN USB_FLOPPY_DEV *UsbFloppyDevice, IN USB_FLOPPY_DEV *UsbFloppyDevice,
IN VOID *Buffer, IN VOID *Buffer,
IN EFI_LBA Lba, IN EFI_LBA Lba,
IN UINTN NumberOfBlocks IN UINTN NumberOfBlocks
) )
/*++ /*++
@ -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,82 +769,56 @@ USBFloppyWrite10 (
while (BlocksRemaining > 0) { while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) { if (BlocksRemaining <= MaxBlock) {
SectorCount = BlocksRemaining; SectorCount = BlocksRemaining;
} else { } else {
SectorCount = MaxBlock; SectorCount = MaxBlock;
} }
//
// fill the Packet data structure
//
Write10Packet->opcode = WRITE_10;
// for (Index = 0; Index < 3; Index ++) {
// 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;
}
}
// //
// 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 ( Status = USBFloppyPacketCommand (
UsbFloppyDevice, UsbFloppyDevice,
&Packet, &Packet,
sizeof (ATAPI_PACKET_COMMAND), sizeof (ATAPI_PACKET_COMMAND),
(VOID *) ptrBuffer, (VOID *) ptrBuffer,
ByteCount, ByteCount,
EfiUsbDataOut, EfiUsbDataOut,
TimeOut TimeOut
); );
if (EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; break;
} }
} }
if (Index == 3) {
return EFI_DEVICE_ERROR;
}
Lba32 += SectorCount; Lba32 += SectorCount;
ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize; ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount); BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
@ -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;