Save original PCI attributes in start() function and restore it in Stop() for those PCI device drivers.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4212 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
vanjeff 2007-10-25 07:59:45 +00:00
parent c9a0a0fcf1
commit 68246fa809
9 changed files with 328 additions and 268 deletions

View File

@ -1,12 +1,12 @@
/** @file
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
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.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@ -51,7 +51,7 @@ static SCSI_COMMAND_SET gSupportedATAPICommands[] = {
{ OP_WRITE_10, DataOut },
{ OP_WRITE_12, DataOut },
{ OP_WRITE_AND_VERIFY, DataOut },
{ 0xff, (DATA_DIRECTION) 0xff }
{ 0xff, (DATA_DIRECTION) 0xff }
};
static CHAR16 *gControllerNameString = (CHAR16 *) L"ATAPI Controller";
@ -163,9 +163,9 @@ AtapiScsiPassThruDriverBindingStart (
)
{
EFI_STATUS Status;
EFI_STATUS DisableStatus;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 Supports;
UINT64 OriginalPciAttributes;
PciIo = NULL;
Status = gBS->OpenProtocol (
@ -180,6 +180,20 @@ AtapiScsiPassThruDriverBindingStart (
return Status;
}
//
// Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&OriginalPciAttributes
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSupported,
@ -204,29 +218,19 @@ AtapiScsiPassThruDriverBindingStart (
//
// Create SCSI Pass Thru instance for the IDE channel.
//
Status = RegisterAtapiScsiPassThru (This, Controller, PciIo);
Status = RegisterAtapiScsiPassThru (This, Controller, PciIo, OriginalPciAttributes);
Done:
if (EFI_ERROR (Status)) {
if (PciIo) {
DisableStatus = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSupported,
0,
&Supports
);
if (!EFI_ERROR (DisableStatus)) {
Supports &= (EFI_PCI_DEVICE_ENABLE |
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
DisableStatus = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
}
}
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
OriginalPciAttributes,
NULL
);
gBS->CloseProtocol (
Controller,
@ -264,7 +268,6 @@ AtapiScsiPassThruDriverBindingStop (
EFI_STATUS Status;
EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
UINT64 Supports;
Status = gBS->OpenProtocol (
Controller,
@ -288,26 +291,16 @@ AtapiScsiPassThruDriverBindingStop (
if (EFI_ERROR (Status)) {
return Status;
}
//
// Release Pci Io protocol on the controller handle.
// Restore original PCI attributes
//
Status = AtapiScsiPrivate->PciIo->Attributes (
AtapiScsiPrivate->PciIo,
EfiPciIoAttributeOperationSupported,
0,
&Supports
);
if (!EFI_ERROR (Status)) {
Supports &= (EFI_PCI_DEVICE_ENABLE |
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
Status = AtapiScsiPrivate->PciIo->Attributes (
AtapiScsiPrivate->PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
}
AtapiScsiPrivate->PciIo->Attributes (
AtapiScsiPrivate->PciIo,
EfiPciIoAttributeOperationSet,
AtapiScsiPrivate->OriginalPciAttributes,
NULL
);
gBS->CloseProtocol (
Controller,
@ -324,8 +317,10 @@ AtapiScsiPassThruDriverBindingStop (
/**
Attaches SCSI Pass Thru Protocol for specified IDE channel.
@param Controller: Parent device handle to the IDE channel.
@param PciIo: PCI I/O protocol attached on the "Controller".
@param Controller: Parent device handle to the IDE channel.
@param PciIo: PCI I/O protocol attached on the "Controller".
@param OriginalPciAttributes Original PCI attributes
@return EFI_SUCCESS Always returned unless installing SCSI Pass Thru Protocol failed.
@ -338,12 +333,12 @@ EFI_STATUS
RegisterAtapiScsiPassThru (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_PCI_IO_PROTOCOL *PciIo
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 OriginalPciAttributes
)
{
EFI_STATUS Status;
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
UINT64 Supports;
IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];
AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));
@ -353,35 +348,15 @@ RegisterAtapiScsiPassThru (
CopyMem (AtapiScsiPrivate->ChannelName, gAtapiChannelString, sizeof (gAtapiChannelString));
//
// Enable channel
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSupported,
0,
&Supports
);
if (!EFI_ERROR (Status)) {
Supports &= (EFI_PCI_DEVICE_ENABLE |
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO |
EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
Supports,
NULL
);
}
AtapiScsiPrivate->Signature = ATAPI_SCSI_PASS_THRU_DEV_SIGNATURE;
AtapiScsiPrivate->Handle = Controller;
//
// will reset the IoPort inside each API function.
//
AtapiScsiPrivate->IoPort = NULL;
AtapiScsiPrivate->PciIo = PciIo;
AtapiScsiPrivate->IoPort = NULL;
AtapiScsiPrivate->PciIo = PciIo;
AtapiScsiPrivate->OriginalPciAttributes = OriginalPciAttributes;
//
// Obtain IDE IO port registers' base addresses
@ -414,7 +389,7 @@ RegisterAtapiScsiPassThru (
//
// non-RAID SCSI controllers should set both physical and logical attributes
//
AtapiScsiPrivate->ScsiPassThruMode.Attributes = EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
AtapiScsiPrivate->ScsiPassThruMode.Attributes = EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
AtapiScsiPrivate->ScsiPassThruMode.IoAlign = 0;
@ -477,7 +452,7 @@ AtapiScsiPassThruFunction (
if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
return EFI_INVALID_PARAMETER;
}
//
// check the data fields in Packet parameter.
//
@ -494,7 +469,7 @@ AtapiScsiPassThruFunction (
Packet->TransferLength = 0;
return EFI_SUCCESS;
}
//
// According to Target ID, reset the Atapi I/O Register mapping
// (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
@ -507,7 +482,7 @@ AtapiScsiPassThruFunction (
Target = Target % 2;
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
}
//
// the ATAPI SCSI interface does not support non-blocking I/O
// ignore the Event parameter
@ -519,7 +494,7 @@ AtapiScsiPassThruFunction (
}
/**
Used to retrieve the list of legal Target IDs for SCSI devices
Used to retrieve the list of legal Target IDs for SCSI devices
on a SCSI channel.
@param This Protocol instance pointer.
@ -592,7 +567,7 @@ AtapiScsiPassThruGetNextDevice (
}
/**
Used to allocate and build a device path node for a SCSI device
Used to allocate and build a device path node for a SCSI device
on a SCSI channel. Would not build device path for a SCSI Host Controller.
@param This Protocol instance pointer.
@ -633,11 +608,11 @@ AtapiScsiPassThruBuildDevicePath (
//
// Validate parameters passed in.
//
if (DevicePath == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// can not build device path for the SCSI Host Controller.
//
@ -703,7 +678,7 @@ AtapiScsiPassThruGetTargetLun (
if (DevicePath == NULL || Target == NULL || Lun == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether the DevicePath belongs to SCSI_DEVICE_PATH
//
@ -726,7 +701,7 @@ AtapiScsiPassThruGetTargetLun (
}
/**
Resets a SCSI channel.This operation resets all the
Resets a SCSI channel.This operation resets all the
SCSI devices connected to the SCSI channel.
@param This Protocol instance pointer.
@ -789,7 +764,7 @@ AtapiScsiPassThruResetChannel (
// 0xfb:1111,1011
//
DeviceControlValue &= 0xfb;
WritePortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Alt.DeviceControl, DeviceControlValue);
//
@ -803,7 +778,7 @@ AtapiScsiPassThruResetChannel (
if (ResetFlag) {
return EFI_SUCCESS;
}
return EFI_TIMEOUT;
}
@ -849,7 +824,7 @@ AtapiScsiPassThruResetTarget (
if (Target == This->Mode->AdapterId) {
return EFI_SUCCESS;
}
//
// According to Target ID, reset the Atapi I/O Register mapping
// (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
@ -860,7 +835,7 @@ AtapiScsiPassThruResetTarget (
} else {
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
}
//
// for ATAPI device, no need to wait DRDY ready after device selecting.
//
@ -880,7 +855,7 @@ AtapiScsiPassThruResetTarget (
if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
return EFI_TIMEOUT;
}
//
// stall 5 seconds to make the device status stable
//
@ -903,13 +878,13 @@ Routine Description:
Arguments:
PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance
IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
receive IDE IO port registers' base addresses
Returns:
EFI_STATUS
--*/
{
EFI_STATUS Status;
@ -934,7 +909,7 @@ Returns:
//
// The BARs should be of IO type
//
if ((PciData.Device.Bar[0] & BIT0) == 0 ||
if ((PciData.Device.Bar[0] & BIT0) == 0 ||
(PciData.Device.Bar[1] & BIT0) == 0) {
return EFI_UNSUPPORTED;
}
@ -978,23 +953,23 @@ Routine Description:
Initialize each Channel's Base Address of CommandBlock and ControlBlock.
Arguments:
AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR
Returns:
None
--*/
--*/
{
UINT8 IdeChannel;
UINT16 CommandBlockBaseAddr;
UINT16 ControlBlockBaseAddr;
IDE_BASE_REGISTERS *RegisterPointer;
for (IdeChannel = 0; IdeChannel < ATAPI_MAX_CHANNEL; IdeChannel++) {
RegisterPointer = &AtapiScsiPrivate->AtapiIoPortRegisters[IdeChannel];
@ -1005,7 +980,7 @@ Returns:
//
CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
RegisterPointer->Data = CommandBlockBaseAddr;
(*(UINT16 *) &RegisterPointer->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
@ -1014,14 +989,14 @@ Returns:
RegisterPointer->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
RegisterPointer->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
(*(UINT16 *) &RegisterPointer->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
(*(UINT16 *) &RegisterPointer->Alt) = ControlBlockBaseAddr;
RegisterPointer->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
}
}
EFI_STATUS
CheckSCSIRequestPacket (
EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
@ -1035,7 +1010,7 @@ Routine Description:
Arguments:
Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
Returns:
@ -1054,7 +1029,7 @@ Returns:
if (Packet->Cdb == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Checks whether the request command is supported.
//
@ -1066,7 +1041,7 @@ Returns:
}
/**
Checks the requested SCSI command:
Checks the requested SCSI command:
Is it supported by this driver?
Is the Data transfer direction reasonable?
@ -1169,7 +1144,7 @@ SubmitBlockingIoCommand (
Packet->SenseDataLength = 0;
return PacketCommandStatus;
}
//
// Check if SenseData meets the alignment requirement.
//
@ -1180,7 +1155,7 @@ SubmitBlockingIoCommand (
}
}
//
// Return SenseData if PacketCommandStatus matches
// the following return codes.
@ -1188,7 +1163,7 @@ SubmitBlockingIoCommand (
if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
(PacketCommandStatus == EFI_DEVICE_ERROR) ||
(PacketCommandStatus == EFI_TIMEOUT)) {
//
// avoid submit request sense command continuously.
//
@ -1678,7 +1653,7 @@ WritePortW (
/**
Check whether DRQ is clear in the Status Register. (BSY must also be cleared)
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -1756,10 +1731,10 @@ StatusDRQClear (
}
/**
Check whether DRQ is clear in the Alternate Status Register.
Check whether DRQ is clear in the Alternate Status Register.
(BSY must also be cleared).
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
DRQ clear. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -1837,7 +1812,7 @@ AltStatusDRQClear (
/**
Check whether DRQ is ready in the Status Register. (BSY must also be cleared)
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -1915,10 +1890,10 @@ StatusDRQReady (
}
/**
Check whether DRQ is ready in the Alternate Status Register.
Check whether DRQ is ready in the Alternate Status Register.
(BSY must also be cleared)
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
DRQ ready. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -1997,7 +1972,7 @@ AltStatusDRQReady (
/**
Check whether BSY is clear in the Status Register.
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -2058,7 +2033,7 @@ StatusWaitForBSYClear (
/**
Check whether BSY is clear in the Alternate Status Register.
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
BSY clear. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -2116,10 +2091,10 @@ AltStatusWaitForBSYClear (
}
/**
Check whether DRDY is ready in the Status Register.
Check whether DRDY is ready in the Status Register.
(BSY must also be cleared)
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -2169,7 +2144,7 @@ StatusDRDYReady (
return EFI_ABORTED;
}
}
//
// Stall for 30 us
//
@ -2192,10 +2167,10 @@ StatusDRDYReady (
}
/**
Check whether DRDY is ready in the Alternate Status Register.
Check whether DRDY is ready in the Alternate Status Register.
(BSY must also be cleared)
If TimeoutInMicroSeconds is zero, this routine should wait infinitely for
DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
DRDY ready. Otherwise, it will return EFI_TIMEOUT when specified time is
elapsed.
@todo function comment is missing 'Routine Description:'
@ -2268,7 +2243,7 @@ AltStatusDRDYReady (
}
/**
Check Error Register for Error Information.
Check Error Register for Error Information.
@todo function comment is missing 'Routine Description:'
@todo function comment is missing 'Arguments:'
@ -2289,7 +2264,7 @@ AtapiPassThruCheckErrorStatus (
AtapiScsiPrivate->PciIo,
AtapiScsiPrivate->IoPort->Reg.Status
);
DEBUG_CODE_BEGIN ();
if (StatusRegister & DWF) {
@ -2310,7 +2285,7 @@ AtapiPassThruCheckErrorStatus (
if (StatusRegister & ERR) {
ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);
if (ErrorRegister & BBK_ERR) {
DEBUG (
@ -2367,16 +2342,16 @@ AtapiPassThruCheckErrorStatus (
return EFI_SUCCESS;
}
return EFI_DEVICE_ERROR;
}
/**
The user Entry Point for module AtapiPassThru. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.

View File

@ -1,12 +1,12 @@
/** @file
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
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.
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: AtapiPassThru.h
@ -102,6 +102,7 @@ typedef struct {
EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru;
EFI_SCSI_PASS_THRU_MODE ScsiPassThruMode;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
//
// Local Data goes here
//
@ -454,6 +455,7 @@ AtapiScsiPassThruDriverEntryPoint (
@param This
@param Controller
@param PciIo
@param OriginalPciAttributes
@todo Add function description
@todo This add argument description
@ -463,9 +465,10 @@ AtapiScsiPassThruDriverEntryPoint (
**/
EFI_STATUS
RegisterAtapiScsiPassThru (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_PCI_IO_PROTOCOL *PciIo
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 OriginalPciAttributes
)
;
@ -971,13 +974,13 @@ Routine Description:
Arguments:
PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance
IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
receive IDE IO port registers' base addresses
Returns:
EFI_STATUS
--*/
;
@ -993,15 +996,15 @@ Routine Description:
Initialize each Channel's Base Address of CommandBlock and ControlBlock.
Arguments:
AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR
Returns:
None
--*/
--*/
;
#endif

View File

@ -133,7 +133,7 @@ EhcReset (
goto ON_EXIT;
}
}
//
// Clean up the asynchronous transfers, currently only
// interrupt supports asynchronous operation.
@ -262,9 +262,9 @@ EhcSetState (
//
// Software must not write a one to this field unless the host controller
// is in the Halted state. Doing so will yield undefined results.
// is in the Halted state. Doing so will yield undefined results.
// refers to Spec[EHCI1.0-2.3.1]
//
//
if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {
Status = EFI_DEVICE_ERROR;
break;
@ -454,7 +454,7 @@ EhcSetRootHubPortFeature (
break;
}
}
//
// Set one to PortReset bit must also set zero to PortEnable bit
//
@ -1395,7 +1395,8 @@ ON_EXIT:
/**
Create and initialize a USB2_HC_DEV
@param PciIo The PciIo on this device
@param PciIo The PciIo on this device
@param OriginalPciAttributes Original PCI attributes
@return The allocated and initialized USB2_HC_DEV structure
@return if created, otherwise NULL.
@ -1404,7 +1405,8 @@ ON_EXIT:
STATIC
USB2_HC_DEV *
EhcCreateUsb2Hc (
IN EFI_PCI_IO_PROTOCOL *PciIo
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 OriginalPciAttributes
)
{
USB2_HC_DEV *Ehc;
@ -1437,7 +1439,8 @@ EhcCreateUsb2Hc (
Ehc->Usb2Hc.MajorRevision = 0x1;
Ehc->Usb2Hc.MinorRevision = 0x1;
Ehc->PciIo = PciIo;
Ehc->PciIo = PciIo;
Ehc->OriginalPciAttributes = OriginalPciAttributes;
InitializeListHead (&Ehc->AsyncIntTransfers);
@ -1492,6 +1495,7 @@ EhcDriverBindingStart (
USB2_HC_DEV *Ehc;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 Supports;
UINT64 OriginalPciAttributes;
//
// Open the PciIo Protocol, then enable the USB host controller
@ -1510,6 +1514,20 @@ EhcDriverBindingStart (
return EFI_DEVICE_ERROR;
}
//
// Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&OriginalPciAttributes
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSupported,
@ -1534,7 +1552,7 @@ EhcDriverBindingStart (
//
// Create then install USB2_HC_PROTOCOL
//
Ehc = EhcCreateUsb2Hc (PciIo);
Ehc = EhcCreateUsb2Hc (PciIo, OriginalPciAttributes);
if (Ehc == NULL) {
EHC_ERROR (("EhcDriverBindingStart: failed to create USB2_HC\n"));
@ -1616,6 +1634,16 @@ FREE_POOL:
gBS->FreePool (Ehc);
CLOSE_PCIIO:
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
OriginalPciAttributes,
NULL
);
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
@ -1653,7 +1681,6 @@ EhcDriverBindingStop (
EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
USB2_HC_DEV *Ehc;
UINT64 Supports;
//
// Test whether the Controller handler passed in is a valid
@ -1704,23 +1731,14 @@ EhcDriverBindingStop (
}
//
// Disable the USB Host Controller
// Restore original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSupported,
0,
&Supports
);
if (!EFI_ERROR (Status)) {
Supports &= EFI_PCI_DEVICE_ENABLE;
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
}
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
Ehc->OriginalPciAttributes,
NULL
);
gBS->CloseProtocol (
Controller,
@ -1729,7 +1747,8 @@ EhcDriverBindingStop (
Controller
);
gBS->FreePool (Ehc);
FreePool (Ehc);
return EFI_SUCCESS;
}

View File

@ -65,11 +65,11 @@ enum {
EHC_ROOT_PORT_RECOVERY_STALL = 20 * EHC_1_MILLISECOND,
//
// Sync and Async transfer polling interval, set by experience,
// Sync and Async transfer polling interval, set by experience,
// and the unit of Async is 100us, means 50ms as interval.
//
EHC_SYNC_POLL_INTERVAL = 20 * EHC_1_MICROSECOND,
EHC_ASYNC_POLL_INTERVAL = 50 * 10000U,
EHC_ASYNC_POLL_INTERVAL = 50 * 10000U,
//
// EHC raises TPL to TPL_NOTIFY to serialize all its operations
@ -111,6 +111,7 @@ struct _USB2_HC_DEV {
EFI_USB2_HC_PROTOCOL Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
USBHC_MEM_POOL *MemPool;
//

View File

@ -82,7 +82,7 @@ UhciReset (
default:
goto ON_INVAILD_PARAMETER;
}
//
// Delete all old transactions on the USB bus, then
// reinitialize the frame list
@ -92,13 +92,13 @@ UhciReset (
UhciInitFrameList (Uhc);
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
ON_INVAILD_PARAMETER:
gBS->RestoreTPL (OldTpl);
return EFI_INVALID_PARAMETER;
}
@ -213,7 +213,7 @@ UhciSetState (
UsbCmd |= USBCMD_FGR;
UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
}
//
// wait 20ms to let resume complete (20ms is specified by UHCI spec)
//
@ -237,7 +237,7 @@ UhciSetState (
Status = EFI_DEVICE_ERROR;
goto ON_EXIT;
}
//
// Set Enter Global Suspend Mode bit to 1.
//
@ -1941,7 +1941,8 @@ ON_EXIT:
STATIC
USB_HC_DEV *
UhciAllocateDev (
IN EFI_PCI_IO_PROTOCOL *PciIo
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 OriginalPciAttributes
)
{
USB_HC_DEV *Uhc;
@ -1990,8 +1991,9 @@ UhciAllocateDev (
Uhc->Usb2Hc.MajorRevision = 0x1;
Uhc->Usb2Hc.MinorRevision = 0x1;
Uhc->PciIo = PciIo;
Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);
Uhc->PciIo = PciIo;
Uhc->OriginalPciAttributes = OriginalPciAttributes;
Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);
if (Uhc->MemPool == NULL) {
Status = EFI_OUT_OF_RESOURCES;
@ -2068,7 +2070,6 @@ UhciCleanDevUp (
)
{
USB_HC_DEV *Uhc;
UINT64 Supports;
//
// Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
@ -2090,20 +2091,16 @@ UhciCleanDevUp (
UhciFreeAllAsyncReq (Uhc);
UhciDestoryFrameList (Uhc);
//
// Restore original PCI attributes
//
Uhc->PciIo->Attributes (
Uhc->PciIo,
EfiPciIoAttributeOperationSupported,
0,
&Supports
);
Supports &= EFI_PCI_DEVICE_ENABLE;
Uhc->PciIo->Attributes (
Uhc->PciIo,
EfiPciIoAttributeOperationDisable,
Supports,
NULL
);
Uhc->PciIo,
EfiPciIoAttributeOperationSet,
Uhc->OriginalPciAttributes,
NULL
);
UhciFreeDev (Uhc);
}
@ -2135,6 +2132,7 @@ UhciDriverBindingStart (
EFI_PCI_IO_PROTOCOL *PciIo;
USB_HC_DEV *Uhc;
UINT64 Supports;
UINT64 OriginalPciAttributes;
//
// Open PCIIO, then enable the EHC device and turn off emulation
@ -2153,6 +2151,20 @@ UhciDriverBindingStart (
return Status;
}
//
// Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&OriginalPciAttributes
);
if (EFI_ERROR (Status)) {
return Status;
}
UhciTurnOffUsbEmulation (PciIo);
Status = PciIo->Attributes (
@ -2175,7 +2187,7 @@ UhciDriverBindingStart (
goto CLOSE_PCIIO;
}
Uhc = UhciAllocateDev (PciIo);
Uhc = UhciAllocateDev (PciIo, OriginalPciAttributes);
if (Uhc == NULL) {
Status = EFI_OUT_OF_RESOURCES;
@ -2250,6 +2262,16 @@ FREE_UHC:
UhciFreeDev (Uhc);
CLOSE_PCIIO:
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
OriginalPciAttributes,
NULL
);
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,

View File

@ -59,28 +59,28 @@ enum {
// UHCI register operation timeout, set by experience
//
UHC_GENERIC_TIMEOUT = UHC_1_SECOND,
//
// Wait for force global resume(FGR) complete, refers to
// specification[UHCI11-2.1.1]
//
//
UHC_FORCE_GLOBAL_RESUME_STALL = 20 * UHC_1_MILLISECOND,
//
// Wait for roothub port reset and recovery, reset stall
// is set by experience, and recovery stall refers to
// is set by experience, and recovery stall refers to
// specification[UHCI11-2.1.1]
//
UHC_ROOT_PORT_RESET_STALL = 50 * UHC_1_MILLISECOND,
UHC_ROOT_PORT_RECOVERY_STALL = 10 * UHC_1_MILLISECOND,
//
// Sync and Async transfer polling interval, set by experience,
// Sync and Async transfer polling interval, set by experience,
// and the unit of Async is 100us.
//
UHC_SYNC_POLL_INTERVAL = 50 * UHC_1_MICROSECOND,
UHC_ASYNC_POLL_INTERVAL = 50 * 10000UL,
//
// UHC raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
@ -117,6 +117,7 @@ struct _USB_HC_DEV {
EFI_USB_HC_PROTOCOL UsbHc;
EFI_USB2_HC_PROTOCOL Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
//
// Schedule data structures

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:
@ -113,15 +113,15 @@ typedef struct CONFIG_HEADER {
//-------------------------------------------------------------------------
// Offsets to the various registers.
// All accesses need not be longword aligned.
// All accesses need not be longword aligned.
//-------------------------------------------------------------------------
enum speedo_offsets {
SCBStatus = 0, SCBCmd = 2, // Rx/Command Unit command and status.
SCBPointer = 4, // General purpose pointer.
SCBPort = 8, // Misc. commands and operands.
SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control.
SCBCtrlMDI = 16, // MDI interface control.
SCBEarlyRx = 20, // Early receive byte count.
SCBStatus = 0, SCBCmd = 2, // Rx/Command Unit command and status.
SCBPointer = 4, // General purpose pointer.
SCBPort = 8, // Misc. commands and operands.
SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control.
SCBCtrlMDI = 16, // MDI interface control.
SCBEarlyRx = 20, // Early receive byte count.
SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27,
// offsets for general control registers (GCRs)
SCBGenCtrl = 28, SCBGenStatus = 29, SCBGenCtrl2 = 30, SCBRsvd = 31
@ -130,7 +130,7 @@ enum speedo_offsets {
#define GCR2_EEPROM_ACCESS_SEMAPHORE 0x80 // bit offset into the gcr2
//-------------------------------------------------------------------------
// Action commands - Commands that can be put in a command list entry.
// Action commands - Commands that can be put in a command list entry.
//-------------------------------------------------------------------------
enum commands {
CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
@ -249,7 +249,7 @@ enum commands {
#define BIT_4_6 0x0070
#define BIT_4_7 0x00F0
#define BIT_5_7 0x00E0
#define BIT_5_9 0x03E0
#define BIT_5_9 0x03E0
#define BIT_5_12 0x1FE0
#define BIT_5_15 0xFFE0
#define BIT_6_7 0x00c0
@ -640,6 +640,10 @@ typedef struct s_data_instance {
UINT64 Unique_ID;
EFI_PCI_IO_PROTOCOL *Io_Function;
//
// Original PCI attributes
//
UINT64 OriginalPciAttributes;
VOID (*Delay_30)(UINTN); // call back routine
VOID (*Virt2Phys_30)(UINT64 virtual_addr, UINT64 physical_ptr); // call back routine

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,7 +22,7 @@ Revision History
--*/
#include "Undi32.h"
#include <Library/BaseLib.h>
//
// Global Variables
//
@ -30,7 +30,7 @@ PXE_SW_UNDI *pxe = 0; // 3.0 entry point
PXE_SW_UNDI *pxe_31 = 0; // 3.1 entry
UNDI32_DEV *UNDI32DeviceList[MAX_NIC_INTERFACES];
NII_TABLE *UnidiDataPointer=NULL;
NII_TABLE *UndiDataPointer = NULL;
VOID
EFIAPI
@ -103,7 +103,7 @@ UndiNotifyExitBs (
Routine Description:
When EFI is shuting down the boot services, we need to install a
When EFI is shuting down the boot services, we need to install a
configuration table for UNDI to work at runtime!
Arguments:
@ -152,15 +152,15 @@ Routine Description:
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to test.
RemainingDevicePath - Not used.
Returns:
EFI_SUCCESS - This driver supports this device.
other - This driver does not support this device.
--*/
@ -266,15 +266,15 @@ Routine Description:
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to work with.
RemainingDevicePath - Not used, always produce all possible children.
Returns:
EFI_SUCCESS - This driver is added to Controller.
other - This driver does not support this device.
--*/
@ -286,7 +286,7 @@ Returns:
UINT16 NewCommand;
UINT8 *TmpPxePointer;
EFI_PCI_IO_PROTOCOL *PciIoFncs;
UINTN Len;
UINTN Len;
UINT64 Supports;
Status = gBS->OpenProtocol (
@ -334,6 +334,20 @@ Returns:
ZeroMem ((CHAR8 *) UNDI32Device, sizeof (UNDI32_DEV));
//
// Get original PCI attributes
//
Status = PciIoFncs->Attributes (
PciIoFncs,
EfiPciIoAttributeOperationGet,
0,
&UNDI32Device->NicInfo.OriginalPciAttributes
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// allocate and initialize both (old and new) the !pxe structures here,
// there should only be one copy of each of these structure for any number
@ -509,22 +523,22 @@ Returns:
}
//
// if the table exists, free it and alloc again, or alloc it directly
// if the table exists, free it and alloc again, or alloc it directly
//
if (UnidiDataPointer != NULL) {
Status = gBS->FreePool(UnidiDataPointer);
if (UndiDataPointer != NULL) {
Status = gBS->FreePool(UndiDataPointer);
}
if (EFI_ERROR (Status)) {
goto UndiErrorDeleteDevicePath;
}
Len = (pxe_31->IFcnt * sizeof (NII_ENTRY)) + sizeof (UnidiDataPointer);
Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UnidiDataPointer);
Len = (pxe_31->IFcnt * sizeof (NII_ENTRY)) + sizeof (UndiDataPointer);
Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UndiDataPointer);
if (EFI_ERROR (Status)) {
goto UndiErrorAllocDataPointer;
}
//
// Open For Child Device
//
@ -563,6 +577,16 @@ UndiErrorDeletePxe:
}
UndiErrorDeleteDevice:
//
// Restore original PCI attributes
//
PciIoFncs->Attributes (
PciIoFncs,
EfiPciIoAttributeOperationSet,
UNDI32Device->NicInfo.OriginalPciAttributes,
NULL
);
gBS->FreePool (UNDI32Device);
UndiError:
@ -659,6 +683,17 @@ Returns:
UNDI32Device = UNDI_DEV_FROM_THIS (NIIProtocol);
//
// Restore original PCI attributes
//
Status = UNDI32Device->NicInfo.Io_Function->Attributes (
UNDI32Device->NicInfo.Io_Function,
EfiPciIoAttributeOperationSet,
UNDI32Device->NicInfo.OriginalPciAttributes,
NULL
);
ASSERT_EFI_ERROR (Status);
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
@ -721,7 +756,7 @@ Routine Description:
Arguments:
UnqId - Runtime O/S routine might use this, this temp routine does not use it
MicroSeconds - Determines the length of pause.
Returns:
@ -751,13 +786,13 @@ Routine Description:
Arguments:
UnqId - Runtime O/S routine may use this field, this temp routine does not.
ReadWrite - Determine if it is an I/O or Memory Read/Write Operation.
Len - Determines the width of the data operation.
Port - What port to Read/Write from.
BuffAddr - Address to read to or write from.
Returns:
@ -851,15 +886,15 @@ Routine Description:
Arguments:
DevPtr - Pointer which will point to the newly created device path with the MAC node attached.
BaseDevPtr - Pointer to the device path which the UNDI device driver is latching on to.
AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
Returns:
EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path.
other - Not enough resources available to create new Device Path node.
--*/
@ -991,7 +1026,7 @@ Arguments:
Returns:
EFI_SUCCESS - Install a GUID/Pointer pair into the system's configuration table.
other - Did not successfully install the GUID/Pointer pair into the configuration table.
--*/
@ -1007,12 +1042,12 @@ Returns:
return EFI_SUCCESS;
}
if(UnidiDataPointer == NULL) {
if(UndiDataPointer == NULL) {
return EFI_SUCCESS;
}
UndiData = (NII_TABLE *)UnidiDataPointer;
UndiData = (NII_TABLE *)UndiDataPointer;
UndiData->NumEntries = pxe_31->IFcnt;
UndiData->NextLink = NULL;
@ -1067,12 +1102,12 @@ Returns:
}
/**
Install driver binding protocol of UNDI.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.

View File

@ -2,13 +2,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.
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:
@ -157,7 +157,7 @@ VOID PhyReset (NIC_DATA_INSTANCE *AdapterInfo);
VOID
MdiWrite (
IN NIC_DATA_INSTANCE *AdapterInfo,
IN UINT8 RegAddress,
IN UINT8 RegAddress,
IN UINT8 PhyAddress,
IN UINT16 DataValue
);
@ -165,7 +165,7 @@ MdiWrite (
VOID
MdiRead(
IN NIC_DATA_INSTANCE *AdapterInfo,
IN UINT8 RegAddress,
IN UINT8 RegAddress,
IN UINT8 PhyAddress,
IN OUT UINT16 *DataValue
);