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

@@ -1,13 +1,13 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
@@ -70,21 +70,21 @@ UsbBotComponentNameGetDriverName (
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
Language - A pointer to a three character ISO 639-2 language identifier.
This is the language of the driver name that that the caller
This is the language of the driver name that that the caller
is requesting, and it must match one of the languages specified
in SupportedLanguages. The number of languages supported by a
in SupportedLanguages. The number of languages supported by a
driver is up to the driver writer.
DriverName - A pointer to the Unicode string to return. This Unicode string
is the name of the driver specified by This in the language
is the name of the driver specified by This in the language
specified by Language.
Returns:
EFI_SUCCESS - The Unicode string for the Driver specified by This
and the language specified by Language was returned
and the language specified by Language was returned
in DriverName.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - DriverName is NULL.
EFI_UNSUPPORTED - The driver specified by This does not support the
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
@@ -114,39 +114,39 @@ UsbBotComponentNameGetControllerName (
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
ControllerHandle - The handle of a controller that the driver specified by
This is managing. This handle specifies the controller
ControllerHandle - The handle of a controller that the driver specified by
This is managing. This handle specifies the controller
whose name is to be returned.
ChildHandle - The handle of the child controller to retrieve the name
of. This is an optional parameter that may be NULL. It
will be NULL for device drivers. It will also be NULL
for a bus drivers that wish to retrieve the name of the
bus controller. It will not be NULL for a bus driver
ChildHandle - The handle of the child controller to retrieve the name
of. This is an optional parameter that may be NULL. It
will be NULL for device drivers. It will also be NULL
for a bus drivers that wish to retrieve the name of the
bus controller. It will not be NULL for a bus driver
that wishes to retrieve the name of a child controller.
Language - A pointer to a three character ISO 639-2 language
identifier. This is the language of the controller name
Language - A pointer to a three character ISO 639-2 language
identifier. This is the language of the controller name
that that the caller is requesting, and it must match one
of the languages specified in SupportedLanguages. The
number of languages supported by a driver is up to the
of the languages specified in SupportedLanguages. The
number of languages supported by a driver is up to the
driver writer.
ControllerName - A pointer to the Unicode string to return. This Unicode
string is the name of the controller specified by
string is the name of the controller specified by
ControllerHandle and ChildHandle in the language specified
by Language from the point of view of the driver specified
by This.
by This.
Returns:
EFI_SUCCESS - The Unicode string for the user readable name in the
language specified by Language for the driver
EFI_SUCCESS - The Unicode string for the user readable name in the
language specified by Language for the driver
specified by This was returned in DriverName.
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - ControllerName is NULL.
EFI_UNSUPPORTED - The driver specified by This is not currently managing
the controller specified by ControllerHandle and
EFI_UNSUPPORTED - The driver specified by This is not currently managing
the controller specified by ControllerHandle and
ChildHandle.
EFI_UNSUPPORTED - The driver specified by This does not support the
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/

View File

@@ -1,13 +1,13 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
@@ -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;
@@ -431,7 +432,7 @@ BotDriverBindingStop (
Returns:
EFI_SUCCESS - This driver is removed DeviceHandle
EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocl
EFI_UNSUPPORTED - Can't open the gEfiUsbAtapiProtocolGuid protocl
other - This driver was not removed from this device
--*/
@@ -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 (
@@ -530,17 +563,12 @@ Arguments:
Returns:
EFI_SUCCESS - Success the operation
--*/
{
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

@@ -1,13 +1,13 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
@@ -22,6 +22,9 @@ Abstract:
#include <IndustryStandard/Usb.h>
extern UINT32 gBOTDebugLevel;
extern UINT32 gBOTErrorLevel;
#define MASS_STORAGE_CLASS 0x08
#pragma pack(1)
//