1. Set the Target array to zero before fill the target id.
2. Get the command/control register base address for each channel through IDE common registers. 3. Correctify some return status to sync with newest Uefi Spec 2.1 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3901 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -12,13 +12,6 @@
|
||||
|
||||
#include "AtapiPassThru.h"
|
||||
|
||||
///
|
||||
/// IDE registers' fixed address
|
||||
///
|
||||
static IDE_BASE_REGISTERS gAtapiIoPortRegisters[2] = {
|
||||
{ 0x1f0, { 0x1f1 }, 0x1f2, 0x1f3, 0x1f4, 0x1f5, 0x1f6, { 0x1f7 }, { 0x3f6 }, 0x3f7, 0 },
|
||||
{ 0x170, { 0x171 }, 0x172, 0x173, 0x174, 0x175, 0x176, { 0x177 }, { 0x376 }, 0x377, 0 }
|
||||
};
|
||||
|
||||
static SCSI_COMMAND_SET gEndTable = { 0xff, (DATA_DIRECTION) 0xff };
|
||||
|
||||
@ -97,6 +90,7 @@ AtapiScsiPassThruDriverBindingSupported (
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
PCI_TYPE00 Pci;
|
||||
|
||||
|
||||
//
|
||||
// Open the IO Abstraction(s) needed to perform the supported test
|
||||
//
|
||||
@ -125,11 +119,11 @@ AtapiScsiPassThruDriverBindingSupported (
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -139,11 +133,11 @@ AtapiScsiPassThruDriverBindingSupported (
|
||||
}
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -169,7 +163,9 @@ AtapiScsiPassThruDriverBindingStart (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS DisableStatus;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT64 Supports;
|
||||
|
||||
PciIo = NULL;
|
||||
Status = gBS->OpenProtocol (
|
||||
@ -186,10 +182,21 @@ AtapiScsiPassThruDriverBindingStart (
|
||||
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
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
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
@ -202,20 +209,31 @@ AtapiScsiPassThruDriverBindingStart (
|
||||
Done:
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (PciIo) {
|
||||
PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
@ -246,6 +264,7 @@ AtapiScsiPassThruDriverBindingStop (
|
||||
EFI_STATUS Status;
|
||||
EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
|
||||
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
|
||||
UINT64 Supports;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
@ -272,19 +291,30 @@ AtapiScsiPassThruDriverBindingStop (
|
||||
//
|
||||
// Release Pci Io protocol on the controller handle.
|
||||
//
|
||||
AtapiScsiPrivate->PciIo->Attributes (
|
||||
AtapiScsiPrivate->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE,
|
||||
NULL
|
||||
);
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
|
||||
gBS->FreePool (AtapiScsiPrivate);
|
||||
|
||||
@ -313,20 +343,36 @@ RegisterAtapiScsiPassThru (
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
|
||||
UINT64 Attributes;
|
||||
UINT64 Supports;
|
||||
IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[ATAPI_MAX_CHANNEL];
|
||||
|
||||
AtapiScsiPrivate = AllocateZeroPool (sizeof (ATAPI_SCSI_PASS_THRU_DEV));
|
||||
if (AtapiScsiPrivate == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Attributes = EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;
|
||||
CopyMem (AtapiScsiPrivate->ChannelName, gAtapiChannelString, sizeof (gAtapiChannelString));
|
||||
|
||||
//
|
||||
// Enable channel
|
||||
//
|
||||
PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSet, Attributes, NULL);
|
||||
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;
|
||||
@ -334,10 +380,19 @@ RegisterAtapiScsiPassThru (
|
||||
//
|
||||
// will reset the IoPort inside each API function.
|
||||
//
|
||||
AtapiScsiPrivate->IoPort = gAtapiIoPortRegisters;
|
||||
AtapiScsiPrivate->IoPort = NULL;
|
||||
AtapiScsiPrivate->PciIo = PciIo;
|
||||
|
||||
//
|
||||
// Obtain IDE IO port registers' base addresses
|
||||
//
|
||||
Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
InitAtapiIoPortRegisters(AtapiScsiPrivate, IdeRegsBaseAddr);
|
||||
|
||||
// initialize SCSI Pass Thru Protocol interface
|
||||
//
|
||||
AtapiScsiPrivate->ScsiPassThru.Mode = &AtapiScsiPrivate->ScsiPassThruMode;
|
||||
@ -364,9 +419,9 @@ RegisterAtapiScsiPassThru (
|
||||
AtapiScsiPrivate->ScsiPassThruMode.IoAlign = 0;
|
||||
|
||||
//
|
||||
// Initialize the LatestTargetId to 0xFFFFFFFF (for the GetNextDevice() call).
|
||||
// Initialize the LatestTargetId.
|
||||
//
|
||||
AtapiScsiPrivate->LatestTargetId = 0xFFFFFFFF;
|
||||
AtapiScsiPrivate->LatestTargetId = 4;
|
||||
AtapiScsiPrivate->LatestLun = 0;
|
||||
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
@ -411,15 +466,15 @@ AtapiScsiPassThruFunction (
|
||||
IN EFI_EVENT Event OPTIONAL
|
||||
)
|
||||
{
|
||||
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
|
||||
EFI_STATUS Status;
|
||||
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
|
||||
EFI_STATUS Status;
|
||||
|
||||
AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Target is not allowed beyond MAX_TARGET_ID
|
||||
//
|
||||
if (Target > MAX_TARGET_ID) {
|
||||
if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -442,13 +497,15 @@ AtapiScsiPassThruFunction (
|
||||
|
||||
//
|
||||
// According to Target ID, reset the Atapi I/O Register mapping
|
||||
// (Target Id in [0,1] area, using gAtapiIoPortRegisters[0],
|
||||
// Target Id in [2,3] area, using gAtapiIoPortRegisters[1]
|
||||
// (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
|
||||
// Target Id in [2,3] area, using AtapiIoPortRegisters[1]
|
||||
//
|
||||
if ((Target / 2) == 0) {
|
||||
AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[0];
|
||||
Target = Target % 2;
|
||||
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
|
||||
} else {
|
||||
AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[1];
|
||||
Target = Target % 2;
|
||||
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
|
||||
}
|
||||
|
||||
//
|
||||
@ -572,6 +629,7 @@ AtapiScsiPassThruBuildDevicePath (
|
||||
{
|
||||
EFI_DEV_PATH *Node;
|
||||
|
||||
|
||||
//
|
||||
// Validate parameters passed in.
|
||||
//
|
||||
@ -691,8 +749,10 @@ AtapiScsiPassThruResetChannel (
|
||||
UINT8 DeviceControlValue;
|
||||
ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate;
|
||||
UINT8 Index;
|
||||
BOOLEAN ResetFlag;
|
||||
|
||||
AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
|
||||
ResetFlag = FALSE;
|
||||
|
||||
//
|
||||
// Reset both Primary channel and Secondary channel.
|
||||
@ -702,7 +762,7 @@ AtapiScsiPassThruResetChannel (
|
||||
//
|
||||
// Reset
|
||||
//
|
||||
AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[Index];
|
||||
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[Index];
|
||||
|
||||
DeviceControlValue = 0;
|
||||
//
|
||||
@ -735,12 +795,16 @@ AtapiScsiPassThruResetChannel (
|
||||
//
|
||||
// slave device needs at most 31s to clear BSY
|
||||
//
|
||||
if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000) == EFI_TIMEOUT) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000) != EFI_TIMEOUT) {
|
||||
ResetFlag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
if (ResetFlag) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -776,7 +840,7 @@ AtapiScsiPassThruResetTarget (
|
||||
|
||||
AtapiScsiPrivate = ATAPI_SCSI_PASS_THRU_DEV_FROM_THIS (This);
|
||||
|
||||
if (Target > MAX_TARGET_ID) {
|
||||
if ((Target > MAX_TARGET_ID) || (Lun != 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
@ -788,13 +852,13 @@ AtapiScsiPassThruResetTarget (
|
||||
|
||||
//
|
||||
// According to Target ID, reset the Atapi I/O Register mapping
|
||||
// (Target Id in [0,1] area, using gAtapiIoPortRegisters[0],
|
||||
// Target Id in [2,3] area, using gAtapiIoPortRegisters[1]
|
||||
// (Target Id in [0,1] area, using AtapiIoPortRegisters[0],
|
||||
// Target Id in [2,3] area, using AtapiIoPortRegisters[1]
|
||||
//
|
||||
if ((Target / 2) == 0) {
|
||||
AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[0];
|
||||
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[0];
|
||||
} else {
|
||||
AtapiScsiPrivate->IoPort = &gAtapiIoPortRegisters[1];
|
||||
AtapiScsiPrivate->IoPort = &AtapiScsiPrivate->AtapiIoPortRegisters[1];
|
||||
}
|
||||
|
||||
//
|
||||
@ -813,8 +877,8 @@ AtapiScsiPassThruResetTarget (
|
||||
// when reset is complete.
|
||||
// slave device needs at most 31s to clear BSY
|
||||
//
|
||||
if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000))) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (EFI_ERROR (StatusWaitForBSYClear (AtapiScsiPrivate, 31000000))) {
|
||||
return EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
//
|
||||
@ -825,25 +889,159 @@ AtapiScsiPassThruResetTarget (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Checks the parameters in the SCSI Request Packet to make sure
|
||||
they are valid for a SCSI Pass Thru request.
|
||||
EFI_STATUS
|
||||
GetIdeRegistersBaseAddr (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
OUT IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
@todo function comment is missing 'Routine Description:'
|
||||
@todo function comment is missing 'Arguments:'
|
||||
@todo function comment is missing 'Returns:'
|
||||
@todo Packet - add argument and description to function comment
|
||||
@todo EFI_INVALID_PARAMETER - add return value to function comment
|
||||
@todo EFI_INVALID_PARAMETER - add return value to function comment
|
||||
@todo EFI_INVALID_PARAMETER - add return value to function comment
|
||||
@todo EFI_UNSUPPORTED - add return value to function comment
|
||||
@todo EFI_SUCCESS - add return value to function comment
|
||||
**/
|
||||
Routine Description:
|
||||
Get IDE IO port registers' base addresses by mode. In 'Compatibility' mode,
|
||||
use fixed addresses. In Native-PCI mode, get base addresses from BARs in
|
||||
the PCI IDE controller's Configuration Space.
|
||||
|
||||
Arguments:
|
||||
PciIo - Pointer to the EFI_PCI_IO_PROTOCOL instance
|
||||
IdeRegsBaseAddr - Pointer to IDE_REGISTERS_BASE_ADDR to
|
||||
receive IDE IO port registers' base addresses
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PCI_TYPE00 PciData;
|
||||
|
||||
Status = PciIo->Pci.Read (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint8,
|
||||
0,
|
||||
sizeof (PciData),
|
||||
&PciData
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
|
||||
IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr = 0x1f0;
|
||||
IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr = 0x3f6;
|
||||
} else {
|
||||
//
|
||||
// The BARs should be of IO type
|
||||
//
|
||||
if ((PciData.Device.Bar[0] & BIT0) == 0 ||
|
||||
(PciData.Device.Bar[1] & BIT0) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
IdeRegsBaseAddr[IdePrimary].CommandBlockBaseAddr =
|
||||
(UINT16) (PciData.Device.Bar[0] & 0x0000fff8);
|
||||
IdeRegsBaseAddr[IdePrimary].ControlBlockBaseAddr =
|
||||
(UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);
|
||||
}
|
||||
|
||||
if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
|
||||
IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr = 0x170;
|
||||
IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr = 0x376;
|
||||
} else {
|
||||
//
|
||||
// The BARs should be of IO type
|
||||
//
|
||||
if ((PciData.Device.Bar[2] & BIT0) == 0 ||
|
||||
(PciData.Device.Bar[3] & BIT0) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
IdeRegsBaseAddr[IdeSecondary].CommandBlockBaseAddr =
|
||||
(UINT16) (PciData.Device.Bar[2] & 0x0000fff8);
|
||||
IdeRegsBaseAddr[IdeSecondary].ControlBlockBaseAddr =
|
||||
(UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
InitAtapiIoPortRegisters (
|
||||
IN ATAPI_SCSI_PASS_THRU_DEV *AtapiScsiPrivate,
|
||||
IN IDE_REGISTERS_BASE_ADDR *IdeRegsBaseAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
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];
|
||||
|
||||
//
|
||||
// Initialize IDE IO port addresses, including Command Block registers
|
||||
// and Control Block registers
|
||||
//
|
||||
CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
|
||||
ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
|
||||
|
||||
RegisterPointer->Data = CommandBlockBaseAddr;
|
||||
(*(UINT16 *) &RegisterPointer->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
|
||||
RegisterPointer->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
|
||||
RegisterPointer->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
|
||||
RegisterPointer->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
|
||||
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
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Checks the parameters in the SCSI Request Packet to make sure
|
||||
they are valid for a SCSI Pass Thru request.
|
||||
|
||||
Arguments:
|
||||
|
||||
Packet - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
if (Packet == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -971,11 +1169,23 @@ SubmitBlockingIoCommand (
|
||||
Packet->SenseDataLength = 0;
|
||||
return PacketCommandStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if SenseData meets the alignment requirement.
|
||||
//
|
||||
if ((AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign != 0) \
|
||||
&& (AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign != 1)) {
|
||||
if (((UINTN)Packet->SenseData % AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Return SenseData if PacketCommandStatus matches
|
||||
// the following return codes.
|
||||
//
|
||||
if ((PacketCommandStatus == EFI_WARN_BUFFER_TOO_SMALL) ||
|
||||
if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||
|
||||
(PacketCommandStatus == EFI_DEVICE_ERROR) ||
|
||||
(PacketCommandStatus == EFI_TIMEOUT)) {
|
||||
|
||||
@ -1096,18 +1306,25 @@ AtapiPacketCommand (
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Set all the command parameters by fill related registers.
|
||||
// Before write to all the following registers, BSY and DRQ must be 0.
|
||||
// Check if the buffer meets the alignment requirement.
|
||||
//
|
||||
Status = StatusDRQClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_ABORTED) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
if ((AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign != 0) \
|
||||
&& (AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign != 1)) {
|
||||
if (((UINTN)Buffer % AtapiScsiPrivate->ScsiPassThru.Mode->IoAlign) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*ByteCount = 0;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Set all the command parameters by fill related registers.
|
||||
// Before write to all the following registers, BSY must be 0.
|
||||
//
|
||||
Status = StatusWaitForBSYClear (AtapiScsiPrivate, TimeoutInMicroSeconds);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Select device via Device/Head Register.
|
||||
// "Target = 0" indicates device 0; "Target = 1" indicates device 1
|
||||
@ -1118,6 +1335,20 @@ AtapiPacketCommand (
|
||||
(UINT8) ((Target << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)
|
||||
);
|
||||
|
||||
//
|
||||
// Set all the command parameters by fill related registers.
|
||||
// Before write to all the following registers, BSY DRQ must be 0.
|
||||
//
|
||||
Status = StatusDRQClear(AtapiScsiPrivate, TimeoutInMicroSeconds);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_ABORTED) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
*ByteCount = 0;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// No OVL; No DMA (by setting feature register)
|
||||
//
|
||||
@ -1282,7 +1513,7 @@ AtapiPassThruPioReadWriteData (
|
||||
// ActualWordCount > 0
|
||||
//
|
||||
if (ActualWordCount < RequiredWordCount) {
|
||||
return EFI_WARN_BUFFER_TOO_SMALL;
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
//
|
||||
|
Reference in New Issue
Block a user