DuetPkg: SataControllerDxe: fix private array subscripting

Each one of the DisqualifiedModes, IdentifyData and IdentifyValid arrays
in the EFI_SATA_CONTROLLER_PRIVATE_DATA structure is a matrix, represented
as a flat array.

The code currently uses the incorrect formula

  Channel * Device

to index them. The right formula is

  [Channel][Device]

which can be implemented as

  Channel * NumDevicePerChannel + Device

Add a helper function that does this, and replace the incorrect
subscripts.

Cc: Alexander Graf <agraf@suse.de>
Cc: Reza Jelveh <reza.jelveh@tuhh.de>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Gabriel L. Somlo <somlo@cmu.edu>
Cc: Feng Tian <feng.tian@intel.com>
Reported-by: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Tested-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18525 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2015-09-22 11:18:13 +00:00 committed by lersek
parent d80e8c459a
commit 83be6beea5
1 changed files with 49 additions and 7 deletions

View File

@ -600,6 +600,37 @@ SataControllerStop (
); );
} }
/**
Calculate the flat array subscript of a (Channel, Device) pair.
@param[in] SataPrivateData The private data structure corresponding to the
SATA controller that attaches the device for
which the flat array subscript is being
calculated.
@param[in] Channel The channel (ie. port) number on the SATA
controller that the device is attached to.
@param[in] Device The device number on the channel.
@return The flat array subscript suitable for indexing DisqualifiedModes,
IdentifyData, and IdentifyValid.
**/
STATIC
UINTN
FlatDeviceIndex (
IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData,
IN UINTN Channel,
IN UINTN Device
)
{
ASSERT (SataPrivateData != NULL);
ASSERT (Channel < SataPrivateData->IdeInit.ChannelCount);
ASSERT (Device < SataPrivateData->DeviceCount);
return Channel * SataPrivateData->DeviceCount + Device;
}
// //
// Interface functions of IDE_CONTROLLER_INIT protocol // Interface functions of IDE_CONTROLLER_INIT protocol
// //
@ -746,6 +777,8 @@ IdeInitSubmitData (
) )
{ {
EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData; EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
UINTN DeviceIndex;
SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
ASSERT (SataPrivateData != NULL); ASSERT (SataPrivateData != NULL);
@ -753,19 +786,21 @@ IdeInitSubmitData (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
// //
// Make a local copy of device's IdentifyData and mark the valid flag // Make a local copy of device's IdentifyData and mark the valid flag
// //
if (IdentifyData != NULL) { if (IdentifyData != NULL) {
CopyMem ( CopyMem (
&(SataPrivateData->IdentifyData[Channel * Device]), &(SataPrivateData->IdentifyData[DeviceIndex]),
IdentifyData, IdentifyData,
sizeof (EFI_IDENTIFY_DATA) sizeof (EFI_IDENTIFY_DATA)
); );
SataPrivateData->IdentifyValid[Channel * Device] = TRUE; SataPrivateData->IdentifyValid[DeviceIndex] = TRUE;
} else { } else {
SataPrivateData->IdentifyValid[Channel * Device] = FALSE; SataPrivateData->IdentifyValid[DeviceIndex] = FALSE;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -821,6 +856,8 @@ IdeInitDisqualifyMode (
) )
{ {
EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData; EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
UINTN DeviceIndex;
SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
ASSERT (SataPrivateData != NULL); ASSERT (SataPrivateData != NULL);
@ -828,12 +865,14 @@ IdeInitDisqualifyMode (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
// //
// Record the disqualified modes per channel per device. From ATA/ATAPI spec, // Record the disqualified modes per channel per device. From ATA/ATAPI spec,
// if a mode is not supported, the modes higher than it is also not supported. // if a mode is not supported, the modes higher than it is also not supported.
// //
CopyMem ( CopyMem (
&(SataPrivateData->DisqualifiedModes[Channel * Device]), &(SataPrivateData->DisqualifiedModes[DeviceIndex]),
BadModes, BadModes,
sizeof (EFI_ATA_COLLECTIVE_MODE) sizeof (EFI_ATA_COLLECTIVE_MODE)
); );
@ -910,6 +949,7 @@ IdeInitCalculateMode (
EFI_ATA_COLLECTIVE_MODE *DisqualifiedModes; EFI_ATA_COLLECTIVE_MODE *DisqualifiedModes;
UINT16 SelectedMode; UINT16 SelectedMode;
EFI_STATUS Status; EFI_STATUS Status;
UINTN DeviceIndex;
SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This); SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
ASSERT (SataPrivateData != NULL); ASSERT (SataPrivateData != NULL);
@ -924,9 +964,11 @@ IdeInitCalculateMode (
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
IdentifyData = &(SataPrivateData->IdentifyData[Channel * Device]); DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
IdentifyValid = SataPrivateData->IdentifyValid[Channel * Device];
DisqualifiedModes = &(SataPrivateData->DisqualifiedModes[Channel * Device]); IdentifyData = &(SataPrivateData->IdentifyData[DeviceIndex]);
IdentifyValid = SataPrivateData->IdentifyValid[DeviceIndex];
DisqualifiedModes = &(SataPrivateData->DisqualifiedModes[DeviceIndex]);
// //
// Make sure we've got the valid identify data of the device from SubmitData() // Make sure we've got the valid identify data of the device from SubmitData()