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

View File

@ -1,12 +1,12 @@
/** @file /** @file
Copyright (c) 2006, Intel Corporation Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: AtapiPassThru.h Module Name: AtapiPassThru.h
@ -102,6 +102,7 @@ typedef struct {
EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru; EFI_SCSI_PASS_THRU_PROTOCOL ScsiPassThru;
EFI_SCSI_PASS_THRU_MODE ScsiPassThruMode; EFI_SCSI_PASS_THRU_MODE ScsiPassThruMode;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
// //
// Local Data goes here // Local Data goes here
// //
@ -454,6 +455,7 @@ AtapiScsiPassThruDriverEntryPoint (
@param This @param This
@param Controller @param Controller
@param PciIo @param PciIo
@param OriginalPciAttributes
@todo Add function description @todo Add function description
@todo This add argument description @todo This add argument description
@ -463,9 +465,10 @@ AtapiScsiPassThruDriverEntryPoint (
**/ **/
EFI_STATUS EFI_STATUS
RegisterAtapiScsiPassThru ( RegisterAtapiScsiPassThru (
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller, 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: Arguments:
PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance 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 receive IDE IO port registers' base addresses
Returns: Returns:
EFI_STATUS EFI_STATUS
--*/ --*/
; ;
@ -993,15 +996,15 @@ Routine Description:
Initialize each Channel's Base Address of CommandBlock and ControlBlock. Initialize each Channel's Base Address of CommandBlock and ControlBlock.
Arguments: Arguments:
AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV AtapiScsiPrivate - The pointer of ATAPI_SCSI_PASS_THRU_DEV
IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr - The pointer of IDE_REGISTERS_BASE_ADDR
Returns: Returns:
None None
--*/ --*/
; ;
#endif #endif

View File

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

View File

@ -65,11 +65,11 @@ enum {
EHC_ROOT_PORT_RECOVERY_STALL = 20 * EHC_1_MILLISECOND, 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. // and the unit of Async is 100us, means 50ms as interval.
// //
EHC_SYNC_POLL_INTERVAL = 20 * EHC_1_MICROSECOND, 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 // 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_USB2_HC_PROTOCOL Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
USBHC_MEM_POOL *MemPool; USBHC_MEM_POOL *MemPool;
// //

View File

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

View File

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

View File

@ -1,13 +1,13 @@
/*++ /*++
Copyright (c) 2006, Intel Corporation Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: Module Name:
@ -113,15 +113,15 @@ typedef struct CONFIG_HEADER {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Offsets to the various registers. // Offsets to the various registers.
// All accesses need not be longword aligned. // All accesses need not be longword aligned.
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
enum speedo_offsets { enum speedo_offsets {
SCBStatus = 0, SCBCmd = 2, // Rx/Command Unit command and status. SCBStatus = 0, SCBCmd = 2, // Rx/Command Unit command and status.
SCBPointer = 4, // General purpose pointer. SCBPointer = 4, // General purpose pointer.
SCBPort = 8, // Misc. commands and operands. SCBPort = 8, // Misc. commands and operands.
SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control. SCBflash = 12, SCBeeprom = 14, // EEPROM and flash memory control.
SCBCtrlMDI = 16, // MDI interface control. SCBCtrlMDI = 16, // MDI interface control.
SCBEarlyRx = 20, // Early receive byte count. SCBEarlyRx = 20, // Early receive byte count.
SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27, SCBEarlyRxInt = 24, SCBFlowCtrlReg = 25, SCBPmdr = 27,
// offsets for general control registers (GCRs) // offsets for general control registers (GCRs)
SCBGenCtrl = 28, SCBGenStatus = 29, SCBGenCtrl2 = 30, SCBRsvd = 31 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 #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 { enum commands {
CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, CmdNOp = 0, CmdIASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
@ -249,7 +249,7 @@ enum commands {
#define BIT_4_6 0x0070 #define BIT_4_6 0x0070
#define BIT_4_7 0x00F0 #define BIT_4_7 0x00F0
#define BIT_5_7 0x00E0 #define BIT_5_7 0x00E0
#define BIT_5_9 0x03E0 #define BIT_5_9 0x03E0
#define BIT_5_12 0x1FE0 #define BIT_5_12 0x1FE0
#define BIT_5_15 0xFFE0 #define BIT_5_15 0xFFE0
#define BIT_6_7 0x00c0 #define BIT_6_7 0x00c0
@ -640,6 +640,10 @@ typedef struct s_data_instance {
UINT64 Unique_ID; UINT64 Unique_ID;
EFI_PCI_IO_PROTOCOL *Io_Function; EFI_PCI_IO_PROTOCOL *Io_Function;
//
// Original PCI attributes
//
UINT64 OriginalPciAttributes;
VOID (*Delay_30)(UINTN); // call back routine VOID (*Delay_30)(UINTN); // call back routine
VOID (*Virt2Phys_30)(UINT64 virtual_addr, UINT64 physical_ptr); // 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 Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: Module Name:
@ -22,7 +22,7 @@ Revision History
--*/ --*/
#include "Undi32.h" #include "Undi32.h"
#include <Library/BaseLib.h>
// //
// Global Variables // Global Variables
// //
@ -30,7 +30,7 @@ PXE_SW_UNDI *pxe = 0; // 3.0 entry point
PXE_SW_UNDI *pxe_31 = 0; // 3.1 entry PXE_SW_UNDI *pxe_31 = 0; // 3.1 entry
UNDI32_DEV *UNDI32DeviceList[MAX_NIC_INTERFACES]; UNDI32_DEV *UNDI32DeviceList[MAX_NIC_INTERFACES];
NII_TABLE *UnidiDataPointer=NULL; NII_TABLE *UndiDataPointer = NULL;
VOID VOID
EFIAPI EFIAPI
@ -103,7 +103,7 @@ UndiNotifyExitBs (
Routine Description: 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! configuration table for UNDI to work at runtime!
Arguments: Arguments:
@ -152,15 +152,15 @@ Routine Description:
Arguments: Arguments:
This - Protocol instance pointer. This - Protocol instance pointer.
Controller - Handle of device to test. Controller - Handle of device to test.
RemainingDevicePath - Not used. RemainingDevicePath - Not used.
Returns: Returns:
EFI_SUCCESS - This driver supports this device. EFI_SUCCESS - This driver supports this device.
other - This driver does not support this device. other - This driver does not support this device.
--*/ --*/
@ -266,15 +266,15 @@ Routine Description:
Arguments: Arguments:
This - Protocol instance pointer. This - Protocol instance pointer.
Controller - Handle of device to work with. Controller - Handle of device to work with.
RemainingDevicePath - Not used, always produce all possible children. RemainingDevicePath - Not used, always produce all possible children.
Returns: Returns:
EFI_SUCCESS - This driver is added to Controller. EFI_SUCCESS - This driver is added to Controller.
other - This driver does not support this device. other - This driver does not support this device.
--*/ --*/
@ -286,7 +286,7 @@ Returns:
UINT16 NewCommand; UINT16 NewCommand;
UINT8 *TmpPxePointer; UINT8 *TmpPxePointer;
EFI_PCI_IO_PROTOCOL *PciIoFncs; EFI_PCI_IO_PROTOCOL *PciIoFncs;
UINTN Len; UINTN Len;
UINT64 Supports; UINT64 Supports;
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
@ -334,6 +334,20 @@ Returns:
ZeroMem ((CHAR8 *) UNDI32Device, sizeof (UNDI32_DEV)); 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, // 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 // 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) { if (UndiDataPointer != NULL) {
Status = gBS->FreePool(UnidiDataPointer); Status = gBS->FreePool(UndiDataPointer);
} }
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto UndiErrorDeleteDevicePath; goto UndiErrorDeleteDevicePath;
} }
Len = (pxe_31->IFcnt * sizeof (NII_ENTRY)) + sizeof (UnidiDataPointer); Len = (pxe_31->IFcnt * sizeof (NII_ENTRY)) + sizeof (UndiDataPointer);
Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UnidiDataPointer); Status = gBS->AllocatePool (EfiRuntimeServicesData, Len, (VOID **) &UndiDataPointer);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto UndiErrorAllocDataPointer; goto UndiErrorAllocDataPointer;
} }
// //
// Open For Child Device // Open For Child Device
// //
@ -563,6 +577,16 @@ UndiErrorDeletePxe:
} }
UndiErrorDeleteDevice: UndiErrorDeleteDevice:
//
// Restore original PCI attributes
//
PciIoFncs->Attributes (
PciIoFncs,
EfiPciIoAttributeOperationSet,
UNDI32Device->NicInfo.OriginalPciAttributes,
NULL
);
gBS->FreePool (UNDI32Device); gBS->FreePool (UNDI32Device);
UndiError: UndiError:
@ -659,6 +683,17 @@ Returns:
UNDI32Device = UNDI_DEV_FROM_THIS (NIIProtocol); 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 ( Status = gBS->CloseProtocol (
Controller, Controller,
&gEfiPciIoProtocolGuid, &gEfiPciIoProtocolGuid,
@ -721,7 +756,7 @@ Routine Description:
Arguments: Arguments:
UnqId - Runtime O/S routine might use this, this temp routine does not use it UnqId - Runtime O/S routine might use this, this temp routine does not use it
MicroSeconds - Determines the length of pause. MicroSeconds - Determines the length of pause.
Returns: Returns:
@ -751,13 +786,13 @@ Routine Description:
Arguments: Arguments:
UnqId - Runtime O/S routine may use this field, this temp routine does not. 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. ReadWrite - Determine if it is an I/O or Memory Read/Write Operation.
Len - Determines the width of the data operation. Len - Determines the width of the data operation.
Port - What port to Read/Write from. Port - What port to Read/Write from.
BuffAddr - Address to read to or write from. BuffAddr - Address to read to or write from.
Returns: Returns:
@ -851,15 +886,15 @@ Routine Description:
Arguments: Arguments:
DevPtr - Pointer which will point to the newly created device path with the MAC node attached. 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. 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.. AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
Returns: Returns:
EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path. EFI_SUCCESS - A MAC address was successfully appended to the Base Device Path.
other - Not enough resources available to create new Device Path node. other - Not enough resources available to create new Device Path node.
--*/ --*/
@ -991,7 +1026,7 @@ Arguments:
Returns: Returns:
EFI_SUCCESS - Install a GUID/Pointer pair into the system's configuration table. 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. other - Did not successfully install the GUID/Pointer pair into the configuration table.
--*/ --*/
@ -1007,12 +1042,12 @@ Returns:
return EFI_SUCCESS; return EFI_SUCCESS;
} }
if(UnidiDataPointer == NULL) { if(UndiDataPointer == NULL) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
UndiData = (NII_TABLE *)UnidiDataPointer; UndiData = (NII_TABLE *)UndiDataPointer;
UndiData->NumEntries = pxe_31->IFcnt; UndiData->NumEntries = pxe_31->IFcnt;
UndiData->NextLink = NULL; UndiData->NextLink = NULL;
@ -1067,12 +1102,12 @@ Returns:
} }
/** /**
Install driver binding protocol of UNDI. 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. @param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully. @retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point. @retval other Some error occurs when executing this entry point.

View File

@ -2,13 +2,13 @@
/*++ /*++
Copyright (c) 2006, Intel Corporation. Copyright (c) 2006, Intel Corporation.
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: Module Name:
@ -157,7 +157,7 @@ VOID PhyReset (NIC_DATA_INSTANCE *AdapterInfo);
VOID VOID
MdiWrite ( MdiWrite (
IN NIC_DATA_INSTANCE *AdapterInfo, IN NIC_DATA_INSTANCE *AdapterInfo,
IN UINT8 RegAddress, IN UINT8 RegAddress,
IN UINT8 PhyAddress, IN UINT8 PhyAddress,
IN UINT16 DataValue IN UINT16 DataValue
); );
@ -165,7 +165,7 @@ MdiWrite (
VOID VOID
MdiRead( MdiRead(
IN NIC_DATA_INSTANCE *AdapterInfo, IN NIC_DATA_INSTANCE *AdapterInfo,
IN UINT8 RegAddress, IN UINT8 RegAddress,
IN UINT8 PhyAddress, IN UINT8 PhyAddress,
IN OUT UINT16 *DataValue IN OUT UINT16 *DataValue
); );