diff options
author | qhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-01-26 04:08:57 +0000 |
---|---|---|
committer | qhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-01-26 04:08:57 +0000 |
commit | 4d1fe68e1ca84cf0d3eec69d20625fa57769de12 (patch) | |
tree | 225a3ba03053fc3b4c1e45b10a185bef52645df2 /EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c | |
parent | 01bf334d2c017095a1776c2c42fe5dd0337cff0a (diff) | |
download | edk2-platforms-4d1fe68e1ca84cf0d3eec69d20625fa57769de12.tar.xz |
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
Diffstat (limited to 'EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c')
-rw-r--r-- | EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c | 435 |
1 files changed, 179 insertions, 256 deletions
diff --git a/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c b/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c index acba154842..37b316f875 100644 --- a/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c +++ b/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c @@ -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
- );
+ for (Index = 0; Index < 3; Index ++) {
+ //
+ // First send ATAPI command through Bot
+ //
+ Status = BotCommandPhase (
+ UsbBotDev,
+ Command,
+ CommandSize,
+ BufferLength,
+ Direction,
+ 10 * 1000
+ );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
- //
- // Send/Get Data if there is a Data Stage
- //
- switch (Direction) {
+ 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)
- );
+ case EfiUsbDataIn:
+ case EfiUsbDataOut:
+ BufferSize = BufferLength;
- break;
+ BotDataStatus = BotDataPhase (
+ UsbBotDev,
+ &BufferSize,
+ DataBuffer,
+ Direction,
+ (UINT16) (TimeOutInMilliSeconds)
+ );
- case EfiUsbNoData:
- break;
- }
-
- //
- // Status Phase
- //
- Status = BotStatusPhase (
- UsbBotDev,
- &TransferStatus,
- TimeOutInMilliSeconds
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
+ if (EFI_ERROR (BotDataStatus)) {
+ DEBUG((gBOTErrorLevel, "BotDataPhase Fail\n"));
+ }
+ break;
- if (TransferStatus == 0x02) {
+ case EfiUsbNoData:
+ break;
+ }
+
+ DataResidue = 0;
//
- // Phase error
+ // Status Phase
//
- BotRecoveryReset (UsbBotDev);
- return EFI_DEVICE_ERROR;
- }
+ Status = BotStatusPhase (
+ UsbBotDev,
+ &DataResidue,
+ 10 * 1000
+ );
- if (TransferStatus == 0x01) {
- return EFI_DEVICE_ERROR;
- }
+ if (EFI_ERROR (Status)) {
+ DEBUG((gBOTErrorLevel, "BotStatusPhase Fail\n"));
+ return Status;
+ }
+ if (!EFI_ERROR (BotDataStatus)) {
+ break;
+ }
+
+ }
return BotDataStatus;
}
|