* [PATCH v4 1/6] EmbeddedPkg: SiI3132: Note that ARM is using this Dxe
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-16 13:34 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH v4 2/6] EmbeddedPkg: SiI3132: Add ScsiProtocol callbacks Jeremy Linton
` (5 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
index 4aab75b..fcd2044 100644
--- a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+++ b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
@@ -29,7 +29,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64
#
# DRIVER_BINDING = gAtaBusDriverBinding
# COMPONENT_NAME = gAtaBusComponentName
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 1/6] EmbeddedPkg: SiI3132: Note that ARM is using this Dxe
2017-03-07 22:15 ` [PATCH v4 1/6] EmbeddedPkg: SiI3132: Note that ARM is using this Dxe Jeremy Linton
@ 2017-03-16 13:34 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-16 13:34 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
Well, the subject doesn't really match the content.
MdeModulePkg: add ARM/AARCH64 to AtaBusDxe VALID_ARCHITECTURES
Is a better match.
And since it's both non-functional and an obvious fix, I'd say you
could send this off to edk2-devel on its own if you change the
subject. (And add MdeModulePkg maintainers on cc.)
/
Leif
On Tue, Mar 07, 2017 at 04:15:06PM -0600, Jeremy Linton wrote:
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> index 4aab75b..fcd2044 100644
> --- a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +++ b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> @@ -29,7 +29,7 @@
> #
> # The following information is for reference only and not required by the build tools.
> #
> -# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64
> #
> # DRIVER_BINDING = gAtaBusDriverBinding
> # COMPONENT_NAME = gAtaBusComponentName
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 2/6] EmbeddedPkg: SiI3132: Add ScsiProtocol callbacks
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
2017-03-07 22:15 ` [PATCH v4 1/6] EmbeddedPkg: SiI3132: Note that ARM is using this Dxe Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-16 14:09 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH v4 3/6] EmbeddedPkg: SiI3132: Add SCSI protocol support to header Jeremy Linton
` (4 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
Create a new module that adds the callbacks to support
the EFI SCSI pass-through protocol. These callbacks
wrap around the existing ATA pass-through callbacks.
In particular the SCSI command submission routine takes
the SCSI command and wraps it with an SATA FIS and
sets the protocol to ATAPI. It then forwards the FIS to
a new routine we will break out of the ATA pass-through
callback that manages the FIS submission to the adapter.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
.../Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c | 424 +++++++++++++++++++++
1 file changed, 424 insertions(+)
create mode 100644 EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
new file mode 100644
index 0000000..66dc473
--- /dev/null
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
@@ -0,0 +1,424 @@
+/** @file
+* ATAPI support for the Silicon Image I3132
+*
+* Copyright (c) 2017, ARM Limited. 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.
+*
+**/
+
+#include "SataSiI3132.h"
+
+#include <IndustryStandard/Atapi.h>
+#include <IndustryStandard/Scsi.h>
+#include <Library/MemoryAllocationLib.h>
+
+STATIC
+EFI_STATUS
+SiI3132IDiscoverAtapi (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN INT32 Port
+ )
+{
+ SATA_SI3132_INSTANCE *SataInstance;
+ SATA_SI3132_PORT *SataPort;
+ EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
+ ATA_IDENTIFY_DATA *Data;
+ EFI_STATUS Status;
+ EFI_ATA_STATUS_BLOCK *Asb;
+ EFI_ATA_COMMAND_BLOCK *Acb;
+
+ SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
+ SataPort = &SataInstance->Ports[Port];
+
+ Asb = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
+ Acb = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_COMMAND_BLOCK)));
+ Data = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ATA_IDENTIFY_DATA)));
+ ZeroMem (Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
+ Acb->AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
+ Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 );
+
+ ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
+ Packet.Acb = Acb;
+ Packet.Asb = Asb;
+ Packet.InDataBuffer = Data;
+ Packet.InTransferLength = sizeof (ATA_IDENTIFY_DATA);
+ Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
+ Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
+
+ Status = SiI3132AtaPassThruCommand (SataInstance, SataPort, 0, &Packet, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "SiI ATAPI IDENTIFY DEVICE FAILURE %d\n", Status));
+ } else {
+ Data->ModelName[39] = 0;
+ }
+
+ FreeAlignedPages (Data, EFI_SIZE_TO_PAGES (sizeof (ATA_IDENTIFY_DATA)));
+ FreeAlignedPages (Acb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_COMMAND_BLOCK)));
+ FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+SiI3132ScsiPassRead (
+ IN SATA_SI3132_INSTANCE *SataInstance,
+ IN SATA_SI3132_PORT *SataPort,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ VOID* PciAllocMapping;
+ EFI_PHYSICAL_ADDRESS PhysBuffer;
+ UINTN InDataBufferLength;
+ VOID *AtaSense;
+ BOOLEAN RequestSense;
+
+ Status = EFI_SUCCESS;
+ PciIo = SataInstance->PciIo;
+ PciAllocMapping = NULL;
+ InDataBufferLength = Packet->InTransferLength;
+ AtaSense = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
+ RequestSense = FALSE;
+
+ DEBUG ((DEBUG_VERBOSE, "SiI3132ScsiPassRead() CDB[0]:%X len=%d\n",
+ ((UINT8*)Packet->Cdb)[0], Packet->InTransferLength));
+
+ if (AtaSense != 0) {
+ if (Packet->InTransferLength != 0) {
+ Status = PciIo->Map (SataInstance->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Packet->InDataBuffer,
+ &InDataBufferLength,
+ &PhysBuffer,
+ &PciAllocMapping);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SiI map() failure %d\n", Status));
+ return Status;
+ }
+ } else {
+ PhysBuffer = 0;
+ }
+ do {
+ // SI "The host driver must populate the area normaly used for the first SGE
+ // with the desired ATAPI command". AKA, put the SCSI CDB itself (not the address)
+ // in the 12 bytes comprising the SGE[0].
+ ZeroMem (&SataPort->HostPRB->Sge[0], sizeof (SATA_SI3132_SGE));
+ CopyMem (&SataPort->HostPRB->Sge[0], (UINT8*)Packet->Cdb, Packet->CdbLength);
+
+ // The SGE for the data buffer
+ SataPort->HostPRB->Sge[1].DataAddressLow = (UINT64)PhysBuffer;
+ SataPort->HostPRB->Sge[1].DataAddressHigh = ((UINT64)(PhysBuffer) >> 32);
+ SataPort->HostPRB->Sge[1].Attributes = SGE_TRM;
+ SataPort->HostPRB->Sge[1].DataCount = Packet->InTransferLength;
+
+ // Create the ATA FIS
+ if (Packet->InTransferLength != 0) {
+ SataPort->HostPRB->Control = PRB_CTRL_PKT_READ;
+ } else {
+ SataPort->HostPRB->Control = 0;
+ }
+
+ SataPort->HostPRB->ProtocolOverride = 0;
+
+ // This is an ATA PACKET command, which encapuslates the ATAPI(sorta SCSI) command
+ SataPort->HostPRB->Fis.FisType = SII_FIS_REGISTER_H2D; // Register - Host to Device FIS
+ SataPort->HostPRB->Fis.Control = SII_FIS_CONTROL_CMD; // Is a command
+ SataPort->HostPRB->Fis.Command = ATA_CMD_PACKET;
+ SataPort->HostPRB->Fis.Features = 1;
+ SataPort->HostPRB->Fis.Fis[0] = 0;
+ SataPort->HostPRB->Fis.Fis[1] = (UINT8) (((UINT64)PhysBuffer) & 0x00ff);
+ SataPort->HostPRB->Fis.Fis[2] = (UINT8) (((UINT64)PhysBuffer) >> 8);
+ SataPort->HostPRB->Fis.Fis[3] = 0x40;
+
+ // Issue this as an ATA command
+ Status = SiI3132IssueCommand (SataPort, PciIo, Packet->Timeout, AtaSense);
+
+ if (RequestSense) {
+ // If we were trying to send a request sense in response to a failure
+ // Check conditions are a normal part of SCSI operation, its expected
+ // that most devices will do a 6/2900 (reset) and 2/2800 (media change)
+ // at startup.
+
+ RequestSense = FALSE;
+ Packet->InTransferLength = 0;
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
+ Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION;
+ Status = EFI_SUCCESS;
+ } else if (!EFI_ERROR (Status)) {
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
+ Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
+ ZeroMem (Packet->SenseData, Packet->SenseDataLength);
+ Packet->SenseDataLength = 0;
+ } else if (Status == EFI_TIMEOUT) {
+ SiI3132HwResetPort (SataPort);
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
+ Packet->SenseDataLength = 0;
+ Packet->InTransferLength = 0;
+ } else {
+ // Assume for now, that if we didn't succeed that it was a check condition.
+ // ATAPI can't autosense on SiI, so lets emulate it with an explicit
+ // request sense into the sense buffer.
+ Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
+ if ((RequestSense == FALSE) && (Packet->SenseDataLength)) {
+ if (Packet->SenseDataLength >= SI_MAX_SENSE) {
+ Packet->SenseDataLength = SI_MAX_SENSE - 1;
+ }
+ Packet->CdbLength = 6; //Request Sense is a 6 byte CDB
+ ZeroMem (Packet->Cdb, SI_MAX_CDB);
+ ((char*)Packet->Cdb)[0] = EFI_SCSI_OP_REQUEST_SENSE;
+ ((char*)Packet->Cdb)[4] = Packet->SenseDataLength;
+
+ ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
+ if (PciAllocMapping) {
+ PciIo->Unmap (PciIo, PciAllocMapping);
+ }
+
+ Packet->InTransferLength = Packet->SenseDataLength;
+ InDataBufferLength = Packet->SenseDataLength;
+ Status = PciIo->Map (SataInstance->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Packet->SenseData,
+ &InDataBufferLength,
+ &PhysBuffer,
+ &PciAllocMapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SiI map() sense failure %d\n", Status));
+ Packet->SenseDataLength = 0;
+ } else {
+ // Everything seems ok, lets issue a SCSI sense
+ RequestSense = TRUE;
+ }
+ }
+ }
+ } while (RequestSense);
+
+ if (PciAllocMapping) {
+ PciIo->Unmap (PciIo, PciAllocMapping);
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "SCSI PassThru Unable to allocate sense buffer\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ return Status;
+}
+
+EFI_STATUS
+SiI3132ScsiPassThru (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+ IN EFI_EVENT Event OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ SATA_SI3132_INSTANCE *SataInstance;
+ SATA_SI3132_PORT *SataPort;
+
+ Status = EFI_SUCCESS;
+ SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
+ SataPort = &SataInstance->Ports[Target[0]];
+ ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
+
+ switch (Packet->DataDirection) {
+ case EFI_EXT_SCSI_DATA_DIRECTION_READ:
+ Status = SiI3132ScsiPassRead (SataInstance,SataPort, Packet);
+ break;
+ case EFI_EXT_SCSI_DATA_DIRECTION_WRITE:
+ // TODO, fill this in if we ever want to connect something
+ // besides a simple CDROM/DVDROM
+ default:
+ DEBUG ((DEBUG_ERROR, "SCSI PassThru Unsupported direction\n"));
+ }
+
+ return Status;
+}
+
+STATIC UINT8 mScsiId[TARGET_MAX_BYTES] = {
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+// With ATA, there are potentially three levels of addressing: port,
+// portmultiplier and LUN. The common disk/cdroms generally are
+// single LUN devices. Further, the standard ATAPI spec doesn't
+// support LUN's. So, lets skip any LUN scanning/addressing.
+//
+// This means we are mapping the SCSI "target" to port/multiplier
+// combinations and leaving the lun alone. Thus, target[0] is the port
+// index, and target[1] is the multiplier index.
+EFI_STATUS
+SiI3132GetNextTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target,
+ IN OUT UINT64 *Lun
+ )
+{
+ EFI_STATUS Status;
+ SATA_SI3132_INSTANCE *SataInstance;
+ UINT8 *Target8;
+ SATA_SI3132_PORT *SataPort;
+ LIST_ENTRY *List;
+ INT32 Multiplier;
+ SATA_SI3132_DEVICE *SataDevice;
+ BOOLEAN Found;
+ INT32 Index;
+
+ Status = EFI_NOT_FOUND;
+ SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
+ DEBUG ((DEBUG_INFO, "SCSI GetNextTargetLun L:%d\n",*Lun));
+ if (!SataInstance) {
+ DEBUG ((DEBUG_ERROR, "SCSI GetNextTargetLun no instance\n",Lun));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Target == NULL || Lun == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*Target == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*Lun > 0) {
+ DEBUG ((DEBUG_ERROR, "SCSI GetNextTargetLun Only supports lun0 at the moment\n",Lun));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Target8 = *Target;
+
+ if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) == 0) {
+ // This is the first time we have been called
+ // start looking for devices on the first port.
+ Index = 0;
+ } else {
+ // otherwise start where we left off
+ Index = Target8[0] + 1;
+ }
+ Found = FALSE;
+
+ while ((Index < SATA_SII3132_MAXPORT) && (!Found)) {
+ SataPort = &(SataInstance->Ports[Index]);
+ List = SataPort->Devices.ForwardLink;
+ Multiplier = 0;
+ while ((List != &SataPort->Devices) && (!Found)) {
+ SataDevice = (SATA_SI3132_DEVICE*)List;
+ if (SataDevice->Atapi) {
+ Found = TRUE;
+ Target8[0] = Index;
+ Target8[1] = Multiplier; //the device on this port (for port multipliers)
+ DEBUG ((DEBUG_INFO, "SCSI GetNextTargetLun found device at %d %d\n",Index,Multiplier));
+ SiI3132IDiscoverAtapi (This, Index);
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+ List = List->ForwardLink;
+ Multiplier++;
+ }
+ Index++;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+SiI3132ScsiBuildDevicePath (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+ )
+{
+ SATA_SI3132_INSTANCE *SataInstance;
+
+ SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
+ DEBUG ((DEBUG_INFO, "SCSI BuildDevicePath T:%d L:%d\n", *Target, Lun));
+
+ if (Lun < 1) {
+ return SiI3132BuildDevicePath (&SataInstance->AtaPassThruProtocol, Target[0], Target[1], DevicePath);
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+SiI3132GetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT8 **Target,
+ OUT UINT64 *Lun
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_UNSUPPORTED;
+ DEBUG ((DEBUG_ERROR, "SCSI GetNextTarget T:%d L:%d\n",*Target,Lun));
+ return Status;
+}
+
+// So normally we would want to do a ATA port reset here (which is generally
+// frowned on with modern SCSI transports (sas, fc, etc) unless all the
+// attached devices are in an error state). But the EFI SCSI protocol isn't
+// specific enough to specify a device for which we want to reset the port.
+// This means we are basically stuck simulating it by resetting all the ports
+// which is bad karma. So lets just claim its unsupported and if we discover
+// that port resets are needed as part of the target/lun reset then consider
+// doing it automatically as part of that path.
+EFI_STATUS
+SiI3132ResetChannel (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ Status = EFI_UNSUPPORTED;
+
+ DEBUG ((DEBUG_ERROR, "SCSI ResetChannel\n"));
+ return Status;
+}
+
+// Just do a device reset here, in the future if we find out that is insufficient
+// try to just reset the SATA port the device is attached to as well.
+EFI_STATUS
+SiI3132ResetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun
+ )
+{
+ EFI_STATUS Status;
+ SATA_SI3132_INSTANCE *SataInstance;
+
+ Status = EFI_NOT_FOUND;
+ SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
+
+ DEBUG ((DEBUG_ERROR, "SCSI ResetTargetLun\n"));
+
+ if (Lun < 1) {
+ Status = SiI3132ResetDevice (&SataInstance->AtaPassThruProtocol,
+ Target[0], Target[1]);
+ }
+ return Status;
+}
+
+EFI_STATUS
+SiI3132GetNextTarget (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_UNSUPPORTED;
+ DEBUG ((DEBUG_VERBOSE, "SCSI GetNextTarget\n"));
+ return Status;
+}
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 2/6] EmbeddedPkg: SiI3132: Add ScsiProtocol callbacks
2017-03-07 22:15 ` [PATCH v4 2/6] EmbeddedPkg: SiI3132: Add ScsiProtocol callbacks Jeremy Linton
@ 2017-03-16 14:09 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-16 14:09 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
On Tue, Mar 07, 2017 at 04:15:07PM -0600, Jeremy Linton wrote:
> Create a new module that adds the callbacks to support
> the EFI SCSI pass-through protocol. These callbacks
> wrap around the existing ATA pass-through callbacks.
> In particular the SCSI command submission routine takes
> the SCSI command and wraps it with an SATA FIS and
> sets the protocol to ATAPI. It then forwards the FIS to
> a new routine we will break out of the ATA pass-through
> callback that manages the FIS submission to the adapter.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> .../Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c | 424 +++++++++++++++++++++
> 1 file changed, 424 insertions(+)
> create mode 100644 EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
>
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
> new file mode 100644
> index 0000000..66dc473
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132ScsiPassThru.c
> @@ -0,0 +1,424 @@
> +/** @file
> +* ATAPI support for the Silicon Image I3132
> +*
> +* Copyright (c) 2017, ARM Limited. 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.
> +*
> +**/
> +
> +#include "SataSiI3132.h"
> +
> +#include <IndustryStandard/Atapi.h>
> +#include <IndustryStandard/Scsi.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +STATIC
> +EFI_STATUS
> +SiI3132IDiscoverAtapi (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN INT32 Port
> + )
> +{
> + SATA_SI3132_INSTANCE *SataInstance;
> + SATA_SI3132_PORT *SataPort;
> + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
> + ATA_IDENTIFY_DATA *Data;
> + EFI_STATUS Status;
> + EFI_ATA_STATUS_BLOCK *Asb;
> + EFI_ATA_COMMAND_BLOCK *Acb;
> +
> + SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
> + SataPort = &SataInstance->Ports[Port];
> +
> + Asb = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
> + Acb = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_COMMAND_BLOCK)));
> + Data = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ATA_IDENTIFY_DATA)));
> + ZeroMem (Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
> + Acb->AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
> + Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 );
What does setting these three bits signify?
I agree it's slightly nicer than the "| 0xe0" in various places in
MdeModulePkg, but as someone who doesn't really know anything about
the ATA protocol, this leaves me no guidance as to what its purpose
is. And some quick googling isn't helping :)
Is there a coherent description that could be used for a #define in
Protocol/AtaPassThru.h?
> +
> + ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
> + Packet.Acb = Acb;
> + Packet.Asb = Asb;
> + Packet.InDataBuffer = Data;
> + Packet.InTransferLength = sizeof (ATA_IDENTIFY_DATA);
> + Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
> + Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
> +
> + Status = SiI3132AtaPassThruCommand (SataInstance, SataPort, 0, &Packet, NULL);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_WARN, "SiI ATAPI IDENTIFY DEVICE FAILURE %d\n", Status));
> + } else {
> + Data->ModelName[39] = 0;
Data->ModelName[sizeof (Data->ModelName) - 1] = 0; ?
Uglier, but clearer that there isn't anything really hacky going on.
> + }
> +
> + FreeAlignedPages (Data, EFI_SIZE_TO_PAGES (sizeof (ATA_IDENTIFY_DATA)));
> + FreeAlignedPages (Acb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_COMMAND_BLOCK)));
> + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
> +
> + return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +SiI3132ScsiPassRead (
> + IN SATA_SI3132_INSTANCE *SataInstance,
> + IN SATA_SI3132_PORT *SataPort,
> + IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
> +{
> + EFI_STATUS Status;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + VOID* PciAllocMapping;
> + EFI_PHYSICAL_ADDRESS PhysBuffer;
> + UINTN InDataBufferLength;
> + VOID *AtaSense;
> + BOOLEAN RequestSense;
> +
> + Status = EFI_SUCCESS;
> + PciIo = SataInstance->PciIo;
> + PciAllocMapping = NULL;
> + InDataBufferLength = Packet->InTransferLength;
> + AtaSense = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));
> + RequestSense = FALSE;
> +
> + DEBUG ((DEBUG_VERBOSE, "SiI3132ScsiPassRead() CDB[0]:%X len=%d\n",
> + ((UINT8*)Packet->Cdb)[0], Packet->InTransferLength));
> +
> + if (AtaSense != 0) {
> + if (Packet->InTransferLength != 0) {
> + Status = PciIo->Map (SataInstance->PciIo,
> + EfiPciIoOperationBusMasterRead,
> + Packet->InDataBuffer,
> + &InDataBufferLength,
> + &PhysBuffer,
> + &PciAllocMapping);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "SiI map() failure %d\n", Status));
> + return Status;
> + }
> + } else {
> + PhysBuffer = 0;
> + }
> + do {
> + // SI "The host driver must populate the area normaly used for the first SGE
> + // with the desired ATAPI command". AKA, put the SCSI CDB itself (not the address)
> + // in the 12 bytes comprising the SGE[0].
> + ZeroMem (&SataPort->HostPRB->Sge[0], sizeof (SATA_SI3132_SGE));
> + CopyMem (&SataPort->HostPRB->Sge[0], (UINT8*)Packet->Cdb, Packet->CdbLength);
> +
> + // The SGE for the data buffer
> + SataPort->HostPRB->Sge[1].DataAddressLow = (UINT64)PhysBuffer;
& MAX_UINT32
to prevent some toolchains from complaining about narrowing conversion?
/
Leif
> + SataPort->HostPRB->Sge[1].DataAddressHigh = ((UINT64)(PhysBuffer) >> 32);
> + SataPort->HostPRB->Sge[1].Attributes = SGE_TRM;
> + SataPort->HostPRB->Sge[1].DataCount = Packet->InTransferLength;
> +
> + // Create the ATA FIS
> + if (Packet->InTransferLength != 0) {
> + SataPort->HostPRB->Control = PRB_CTRL_PKT_READ;
> + } else {
> + SataPort->HostPRB->Control = 0;
> + }
> +
> + SataPort->HostPRB->ProtocolOverride = 0;
> +
> + // This is an ATA PACKET command, which encapuslates the ATAPI(sorta SCSI) command
> + SataPort->HostPRB->Fis.FisType = SII_FIS_REGISTER_H2D; // Register - Host to Device FIS
> + SataPort->HostPRB->Fis.Control = SII_FIS_CONTROL_CMD; // Is a command
> + SataPort->HostPRB->Fis.Command = ATA_CMD_PACKET;
> + SataPort->HostPRB->Fis.Features = 1;
> + SataPort->HostPRB->Fis.Fis[0] = 0;
> + SataPort->HostPRB->Fis.Fis[1] = (UINT8) (((UINT64)PhysBuffer) & 0x00ff);
> + SataPort->HostPRB->Fis.Fis[2] = (UINT8) (((UINT64)PhysBuffer) >> 8);
> + SataPort->HostPRB->Fis.Fis[3] = 0x40;
> +
> + // Issue this as an ATA command
> + Status = SiI3132IssueCommand (SataPort, PciIo, Packet->Timeout, AtaSense);
> +
> + if (RequestSense) {
> + // If we were trying to send a request sense in response to a failure
> + // Check conditions are a normal part of SCSI operation, its expected
> + // that most devices will do a 6/2900 (reset) and 2/2800 (media change)
> + // at startup.
> +
> + RequestSense = FALSE;
> + Packet->InTransferLength = 0;
> + Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
> + Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION;
> + Status = EFI_SUCCESS;
> + } else if (!EFI_ERROR (Status)) {
> + Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
> + Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
> + ZeroMem (Packet->SenseData, Packet->SenseDataLength);
> + Packet->SenseDataLength = 0;
> + } else if (Status == EFI_TIMEOUT) {
> + SiI3132HwResetPort (SataPort);
> + Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
> + Packet->SenseDataLength = 0;
> + Packet->InTransferLength = 0;
> + } else {
> + // Assume for now, that if we didn't succeed that it was a check condition.
> + // ATAPI can't autosense on SiI, so lets emulate it with an explicit
> + // request sense into the sense buffer.
> + Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
> + if ((RequestSense == FALSE) && (Packet->SenseDataLength)) {
> + if (Packet->SenseDataLength >= SI_MAX_SENSE) {
> + Packet->SenseDataLength = SI_MAX_SENSE - 1;
> + }
> + Packet->CdbLength = 6; //Request Sense is a 6 byte CDB
> + ZeroMem (Packet->Cdb, SI_MAX_CDB);
> + ((char*)Packet->Cdb)[0] = EFI_SCSI_OP_REQUEST_SENSE;
> + ((char*)Packet->Cdb)[4] = Packet->SenseDataLength;
> +
> + ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
> + if (PciAllocMapping) {
> + PciIo->Unmap (PciIo, PciAllocMapping);
> + }
> +
> + Packet->InTransferLength = Packet->SenseDataLength;
> + InDataBufferLength = Packet->SenseDataLength;
> + Status = PciIo->Map (SataInstance->PciIo,
> + EfiPciIoOperationBusMasterRead,
> + Packet->SenseData,
> + &InDataBufferLength,
> + &PhysBuffer,
> + &PciAllocMapping);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "SiI map() sense failure %d\n", Status));
> + Packet->SenseDataLength = 0;
> + } else {
> + // Everything seems ok, lets issue a SCSI sense
> + RequestSense = TRUE;
> + }
> + }
> + }
> + } while (RequestSense);
> +
> + if (PciAllocMapping) {
> + PciIo->Unmap (PciIo, PciAllocMapping);
> + }
> + } else {
> + DEBUG ((DEBUG_ERROR, "SCSI PassThru Unable to allocate sense buffer\n"));
> + Status = EFI_OUT_OF_RESOURCES;
> + }
> + return Status;
> +}
> +
> +EFI_STATUS
> +SiI3132ScsiPassThru (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun,
> + IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
> + IN EFI_EVENT Event OPTIONAL
> + )
> +{
> + EFI_STATUS Status;
> + SATA_SI3132_INSTANCE *SataInstance;
> + SATA_SI3132_PORT *SataPort;
> +
> + Status = EFI_SUCCESS;
> + SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
> + SataPort = &SataInstance->Ports[Target[0]];
> + ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
> +
> + switch (Packet->DataDirection) {
> + case EFI_EXT_SCSI_DATA_DIRECTION_READ:
> + Status = SiI3132ScsiPassRead (SataInstance,SataPort, Packet);
> + break;
> + case EFI_EXT_SCSI_DATA_DIRECTION_WRITE:
> + // TODO, fill this in if we ever want to connect something
> + // besides a simple CDROM/DVDROM
> + default:
> + DEBUG ((DEBUG_ERROR, "SCSI PassThru Unsupported direction\n"));
> + }
> +
> + return Status;
> +}
> +
> +STATIC UINT8 mScsiId[TARGET_MAX_BYTES] = {
> + 0xFF, 0xFF, 0xFF, 0xFF,
> + 0xFF, 0xFF, 0xFF, 0xFF,
> + 0xFF, 0xFF, 0xFF, 0xFF,
> + 0xFF, 0xFF, 0xFF, 0xFF
> +};
> +
> +// With ATA, there are potentially three levels of addressing: port,
> +// portmultiplier and LUN. The common disk/cdroms generally are
> +// single LUN devices. Further, the standard ATAPI spec doesn't
> +// support LUN's. So, lets skip any LUN scanning/addressing.
> +//
> +// This means we are mapping the SCSI "target" to port/multiplier
> +// combinations and leaving the lun alone. Thus, target[0] is the port
> +// index, and target[1] is the multiplier index.
> +EFI_STATUS
> +SiI3132GetNextTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN OUT UINT8 **Target,
> + IN OUT UINT64 *Lun
> + )
> +{
> + EFI_STATUS Status;
> + SATA_SI3132_INSTANCE *SataInstance;
> + UINT8 *Target8;
> + SATA_SI3132_PORT *SataPort;
> + LIST_ENTRY *List;
> + INT32 Multiplier;
> + SATA_SI3132_DEVICE *SataDevice;
> + BOOLEAN Found;
> + INT32 Index;
> +
> + Status = EFI_NOT_FOUND;
> + SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
> + DEBUG ((DEBUG_INFO, "SCSI GetNextTargetLun L:%d\n",*Lun));
> + if (!SataInstance) {
> + DEBUG ((DEBUG_ERROR, "SCSI GetNextTargetLun no instance\n",Lun));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Target == NULL || Lun == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + if (*Target == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (*Lun > 0) {
> + DEBUG ((DEBUG_ERROR, "SCSI GetNextTargetLun Only supports lun0 at the moment\n",Lun));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Target8 = *Target;
> +
> + if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) == 0) {
> + // This is the first time we have been called
> + // start looking for devices on the first port.
> + Index = 0;
> + } else {
> + // otherwise start where we left off
> + Index = Target8[0] + 1;
> + }
> + Found = FALSE;
> +
> + while ((Index < SATA_SII3132_MAXPORT) && (!Found)) {
> + SataPort = &(SataInstance->Ports[Index]);
> + List = SataPort->Devices.ForwardLink;
> + Multiplier = 0;
> + while ((List != &SataPort->Devices) && (!Found)) {
> + SataDevice = (SATA_SI3132_DEVICE*)List;
> + if (SataDevice->Atapi) {
> + Found = TRUE;
> + Target8[0] = Index;
> + Target8[1] = Multiplier; //the device on this port (for port multipliers)
> + DEBUG ((DEBUG_INFO, "SCSI GetNextTargetLun found device at %d %d\n",Index,Multiplier));
> + SiI3132IDiscoverAtapi (This, Index);
> +
> + Status = EFI_SUCCESS;
> + break;
> + }
> + List = List->ForwardLink;
> + Multiplier++;
> + }
> + Index++;
> + }
> +
> + return Status;
> +}
> +
> +EFI_STATUS
> +SiI3132ScsiBuildDevicePath (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun,
> + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> + )
> +{
> + SATA_SI3132_INSTANCE *SataInstance;
> +
> + SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
> + DEBUG ((DEBUG_INFO, "SCSI BuildDevicePath T:%d L:%d\n", *Target, Lun));
> +
> + if (Lun < 1) {
> + return SiI3132BuildDevicePath (&SataInstance->AtaPassThruProtocol, Target[0], Target[1], DevicePath);
> + }
> + return EFI_NOT_FOUND;
> +}
> +
> +EFI_STATUS
> +SiI3132GetTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> + OUT UINT8 **Target,
> + OUT UINT64 *Lun
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = EFI_UNSUPPORTED;
> + DEBUG ((DEBUG_ERROR, "SCSI GetNextTarget T:%d L:%d\n",*Target,Lun));
> + return Status;
> +}
> +
> +// So normally we would want to do a ATA port reset here (which is generally
> +// frowned on with modern SCSI transports (sas, fc, etc) unless all the
> +// attached devices are in an error state). But the EFI SCSI protocol isn't
> +// specific enough to specify a device for which we want to reset the port.
> +// This means we are basically stuck simulating it by resetting all the ports
> +// which is bad karma. So lets just claim its unsupported and if we discover
> +// that port resets are needed as part of the target/lun reset then consider
> +// doing it automatically as part of that path.
> +EFI_STATUS
> +SiI3132ResetChannel (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
> + )
> +{
> + EFI_STATUS Status;
> + Status = EFI_UNSUPPORTED;
> +
> + DEBUG ((DEBUG_ERROR, "SCSI ResetChannel\n"));
> + return Status;
> +}
> +
> +// Just do a device reset here, in the future if we find out that is insufficient
> +// try to just reset the SATA port the device is attached to as well.
> +EFI_STATUS
> +SiI3132ResetTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun
> + )
> +{
> + EFI_STATUS Status;
> + SATA_SI3132_INSTANCE *SataInstance;
> +
> + Status = EFI_NOT_FOUND;
> + SataInstance = INSTANCE_FROM_SCSIPASSTHRU_THIS (This);
> +
> + DEBUG ((DEBUG_ERROR, "SCSI ResetTargetLun\n"));
> +
> + if (Lun < 1) {
> + Status = SiI3132ResetDevice (&SataInstance->AtaPassThruProtocol,
> + Target[0], Target[1]);
> + }
> + return Status;
> +}
> +
> +EFI_STATUS
> +SiI3132GetNextTarget (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN OUT UINT8 **Target
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = EFI_UNSUPPORTED;
> + DEBUG ((DEBUG_VERBOSE, "SCSI GetNextTarget\n"));
> + return Status;
> +}
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 3/6] EmbeddedPkg: SiI3132: Add SCSI protocol support to header
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
2017-03-07 22:15 ` [PATCH v4 1/6] EmbeddedPkg: SiI3132: Note that ARM is using this Dxe Jeremy Linton
2017-03-07 22:15 ` [PATCH v4 2/6] EmbeddedPkg: SiI3132: Add ScsiProtocol callbacks Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-16 14:19 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH v4 4/6] EmbeddedPkg: SiI3132: Break out FIS command submission Jeremy Linton
` (3 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
Add EXT_SCSI_PASS_THRU structures to SI3132_PORT structure,
along with helpers and new entry points.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h | 103 ++++++++++++++++++++---
1 file changed, 93 insertions(+), 10 deletions(-)
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
index a7bc956..99c2f26 100644
--- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
@@ -1,7 +1,7 @@
/** @file
* Header containing the structure specific to the Silicon Image I3132 Sata PCI card
*
-* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -20,6 +20,7 @@
#include <Protocol/AtaPassThru.h>
#include <Protocol/PciIo.h>
+#include <Protocol/ScsiPassThruExt.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
@@ -57,6 +58,7 @@
#define SII3132_PORT_SLOTSTATUS_REG 0x1800
#define SII3132_PORT_CMDACTIV_REG 0x1C00
#define SII3132_PORT_SSTATUS_REG 0x1F04
+#define SII3132_PORT_SERROR_REG 0x1F08
#define SII3132_PORT_CONTROL_RESET (1 << 0)
#define SII3132_PORT_DEVICE_RESET (1 << 1)
@@ -81,6 +83,7 @@
#define PRB_CTRL_INT_MASK 0x40
#define PRB_CTRL_SRST 0x80
+#define PRB_PROT_DEFAULT 0x00
#define PRB_PROT_PACKET 0x01
#define PRB_PROT_LEGACY_QUEUE 0x02
#define PRB_PROT_NATIVE_QUEUE 0x04
@@ -88,11 +91,18 @@
#define PRB_PROT_WRITE 0x10
#define PRB_PROT_TRANSPARENT 0x20
+#define SII_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device
+#define SII_FIS_CONTROL_CMD (1 << 7) //Indicate FIS is a command
+
#define SGE_XCF (1 << 28)
#define SGE_DRD (1 << 29)
#define SGE_LNK (1 << 30)
#define SGE_TRM 0x80000000
+#define SI_MAX_CDB 12 //MAX supported CDB
+#define SI_MAX_SENSE 256
+#define SI_DEFAULT_TIMEOUT 50000
+
typedef struct _SATA_SI3132_SGE {
UINT32 DataAddressLow;
UINT32 DataAddressHigh;
@@ -121,6 +131,8 @@ typedef struct _SATA_SI3132_DEVICE {
UINTN Index;
struct _SATA_SI3132_PORT *Port; //Parent Port
UINT32 BlockSize;
+ BOOLEAN Atapi; //ATAPI device
+ BOOLEAN Cdb16; //Uses 16byte CDB transfers (or 12)
} SATA_SI3132_DEVICE;
typedef struct _SATA_SI3132_PORT {
@@ -137,17 +149,19 @@ typedef struct _SATA_SI3132_PORT {
} SATA_SI3132_PORT;
typedef struct _SATA_SI3132_INSTANCE {
- UINTN Signature;
-
- SATA_SI3132_PORT Ports[SATA_SII3132_MAXPORT];
-
- EFI_ATA_PASS_THRU_PROTOCOL AtaPassThruProtocol;
-
- EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Signature;
+
+ SATA_SI3132_PORT Ports[SATA_SII3132_MAXPORT];
+ EFI_ATA_PASS_THRU_MODE AtaPassThruMode;
+ EFI_ATA_PASS_THRU_PROTOCOL AtaPassThruProtocol;
+ EFI_EXT_SCSI_PASS_THRU_MODE ExtScsiPassThruMode;
+ EFI_EXT_SCSI_PASS_THRU_PROTOCOL ExtScsiPassThru;
+ EFI_PCI_IO_PROTOCOL *PciIo;
} SATA_SI3132_INSTANCE;
#define SATA_SII3132_SIGNATURE SIGNATURE_32('s', 'i', '3', '2')
-#define INSTANCE_FROM_ATAPASSTHRU_THIS(a) CR(a, SATA_SI3132_INSTANCE, AtaPassThruProtocol, SATA_SII3132_SIGNATURE)
+#define INSTANCE_FROM_ATAPASSTHRU_THIS(a) CR (a, SATA_SI3132_INSTANCE, AtaPassThruProtocol, SATA_SII3132_SIGNATURE)
+#define INSTANCE_FROM_SCSIPASSTHRU_THIS(a) CR (a, SATA_SI3132_INSTANCE, ExtScsiPassThru, SATA_SII3132_SIGNATURE)
#define SATA_GLOBAL_READ32(Offset, Value) PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 0, Offset, 1, Value)
#define SATA_GLOBAL_WRITE32(Offset, Value) { UINT32 Value32 = Value; PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 0, Offset, 1, &Value32); }
@@ -155,7 +169,7 @@ typedef struct _SATA_SI3132_INSTANCE {
#define SATA_PORT_READ32(Offset, Value) PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, Value)
#define SATA_PORT_WRITE32(Offset, Value) { UINT32 Value32 = Value; PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value32); }
-#define SATA_TRACE(txt) DEBUG((EFI_D_VERBOSE, "ARM_SATA: " txt "\n"))
+#define SATA_TRACE(txt) DEBUG ((DEBUG_VERBOSE, "ARM_SATA: " txt "\n"))
extern EFI_COMPONENT_NAME_PROTOCOL gSataSiI3132ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gSataSiI3132ComponentName2;
@@ -266,4 +280,73 @@ EFI_STATUS SiI3132ResetDevice (
IN UINT16 PortMultiplierPort
);
+/**
+ * EFI ATA Pass Thru Entry points for SCSI Protocol
+ */
+SATA_SI3132_DEVICE* GetSataDevice (
+ IN SATA_SI3132_INSTANCE *SataInstance,
+ IN UINT16 Port,
+ IN UINT16 PortMultiplierPort
+ );
+
+EFI_STATUS SiI3132IssueCommand (
+ IN SATA_SI3132_PORT *SataPort,
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Timeout,
+ VOID *StatusBlock
+ );
+
+/**
+ * EFI SCSI Pass Thru Protocol
+ */
+EFI_STATUS SiI3132ScsiPassThru (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
+ IN EFI_EVENT Event OPTIONAL
+ );
+
+EFI_STATUS SiI3132GetNextTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target,
+ IN OUT UINT64 *Lun
+);
+
+EFI_STATUS SiI3132GetNextTargetLun2 (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+ );
+
+EFI_STATUS SiI3132ScsiBuildDevicePath (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+ );
+
+EFI_STATUS SiI3132GetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT8 **Target,
+ OUT UINT64 *Lun
+ );
+
+EFI_STATUS SiI3132ResetChannel (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
+ );
+
+EFI_STATUS SiI3132ResetTargetLun (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN UINT8 *Target,
+ IN UINT64 Lun
+ );
+
+EFI_STATUS SiI3132GetNextTarget (
+ IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT8 **Target
+ );
+
#endif
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 3/6] EmbeddedPkg: SiI3132: Add SCSI protocol support to header
2017-03-07 22:15 ` [PATCH v4 3/6] EmbeddedPkg: SiI3132: Add SCSI protocol support to header Jeremy Linton
@ 2017-03-16 14:19 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-16 14:19 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
On Tue, Mar 07, 2017 at 04:15:08PM -0600, Jeremy Linton wrote:
> Add EXT_SCSI_PASS_THRU structures to SI3132_PORT structure,
> along with helpers and new entry points.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
LGTM
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
> EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h | 103 ++++++++++++++++++++---
> 1 file changed, 93 insertions(+), 10 deletions(-)
>
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
> index a7bc956..99c2f26 100644
> --- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.h
> @@ -1,7 +1,7 @@
> /** @file
> * Header containing the structure specific to the Silicon Image I3132 Sata PCI card
> *
> -* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
> +* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
> *
> * This program and the accompanying materials
> * are licensed and made available under the terms and conditions of the BSD License
> @@ -20,6 +20,7 @@
>
> #include <Protocol/AtaPassThru.h>
> #include <Protocol/PciIo.h>
> +#include <Protocol/ScsiPassThruExt.h>
>
> #include <Library/UefiLib.h>
> #include <Library/DebugLib.h>
> @@ -57,6 +58,7 @@
> #define SII3132_PORT_SLOTSTATUS_REG 0x1800
> #define SII3132_PORT_CMDACTIV_REG 0x1C00
> #define SII3132_PORT_SSTATUS_REG 0x1F04
> +#define SII3132_PORT_SERROR_REG 0x1F08
>
> #define SII3132_PORT_CONTROL_RESET (1 << 0)
> #define SII3132_PORT_DEVICE_RESET (1 << 1)
> @@ -81,6 +83,7 @@
> #define PRB_CTRL_INT_MASK 0x40
> #define PRB_CTRL_SRST 0x80
>
> +#define PRB_PROT_DEFAULT 0x00
> #define PRB_PROT_PACKET 0x01
> #define PRB_PROT_LEGACY_QUEUE 0x02
> #define PRB_PROT_NATIVE_QUEUE 0x04
> @@ -88,11 +91,18 @@
> #define PRB_PROT_WRITE 0x10
> #define PRB_PROT_TRANSPARENT 0x20
>
> +#define SII_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device
> +#define SII_FIS_CONTROL_CMD (1 << 7) //Indicate FIS is a command
> +
> #define SGE_XCF (1 << 28)
> #define SGE_DRD (1 << 29)
> #define SGE_LNK (1 << 30)
> #define SGE_TRM 0x80000000
>
> +#define SI_MAX_CDB 12 //MAX supported CDB
> +#define SI_MAX_SENSE 256
> +#define SI_DEFAULT_TIMEOUT 50000
> +
> typedef struct _SATA_SI3132_SGE {
> UINT32 DataAddressLow;
> UINT32 DataAddressHigh;
> @@ -121,6 +131,8 @@ typedef struct _SATA_SI3132_DEVICE {
> UINTN Index;
> struct _SATA_SI3132_PORT *Port; //Parent Port
> UINT32 BlockSize;
> + BOOLEAN Atapi; //ATAPI device
> + BOOLEAN Cdb16; //Uses 16byte CDB transfers (or 12)
> } SATA_SI3132_DEVICE;
>
> typedef struct _SATA_SI3132_PORT {
> @@ -137,17 +149,19 @@ typedef struct _SATA_SI3132_PORT {
> } SATA_SI3132_PORT;
>
> typedef struct _SATA_SI3132_INSTANCE {
> - UINTN Signature;
> -
> - SATA_SI3132_PORT Ports[SATA_SII3132_MAXPORT];
> -
> - EFI_ATA_PASS_THRU_PROTOCOL AtaPassThruProtocol;
> -
> - EFI_PCI_IO_PROTOCOL *PciIo;
> + UINTN Signature;
> +
> + SATA_SI3132_PORT Ports[SATA_SII3132_MAXPORT];
> + EFI_ATA_PASS_THRU_MODE AtaPassThruMode;
> + EFI_ATA_PASS_THRU_PROTOCOL AtaPassThruProtocol;
> + EFI_EXT_SCSI_PASS_THRU_MODE ExtScsiPassThruMode;
> + EFI_EXT_SCSI_PASS_THRU_PROTOCOL ExtScsiPassThru;
> + EFI_PCI_IO_PROTOCOL *PciIo;
> } SATA_SI3132_INSTANCE;
>
> #define SATA_SII3132_SIGNATURE SIGNATURE_32('s', 'i', '3', '2')
> -#define INSTANCE_FROM_ATAPASSTHRU_THIS(a) CR(a, SATA_SI3132_INSTANCE, AtaPassThruProtocol, SATA_SII3132_SIGNATURE)
> +#define INSTANCE_FROM_ATAPASSTHRU_THIS(a) CR (a, SATA_SI3132_INSTANCE, AtaPassThruProtocol, SATA_SII3132_SIGNATURE)
> +#define INSTANCE_FROM_SCSIPASSTHRU_THIS(a) CR (a, SATA_SI3132_INSTANCE, ExtScsiPassThru, SATA_SII3132_SIGNATURE)
>
> #define SATA_GLOBAL_READ32(Offset, Value) PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 0, Offset, 1, Value)
> #define SATA_GLOBAL_WRITE32(Offset, Value) { UINT32 Value32 = Value; PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 0, Offset, 1, &Value32); }
> @@ -155,7 +169,7 @@ typedef struct _SATA_SI3132_INSTANCE {
> #define SATA_PORT_READ32(Offset, Value) PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, Value)
> #define SATA_PORT_WRITE32(Offset, Value) { UINT32 Value32 = Value; PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, Offset, 1, &Value32); }
>
> -#define SATA_TRACE(txt) DEBUG((EFI_D_VERBOSE, "ARM_SATA: " txt "\n"))
> +#define SATA_TRACE(txt) DEBUG ((DEBUG_VERBOSE, "ARM_SATA: " txt "\n"))
>
> extern EFI_COMPONENT_NAME_PROTOCOL gSataSiI3132ComponentName;
> extern EFI_COMPONENT_NAME2_PROTOCOL gSataSiI3132ComponentName2;
> @@ -266,4 +280,73 @@ EFI_STATUS SiI3132ResetDevice (
> IN UINT16 PortMultiplierPort
> );
>
> +/**
> + * EFI ATA Pass Thru Entry points for SCSI Protocol
> + */
> +SATA_SI3132_DEVICE* GetSataDevice (
> + IN SATA_SI3132_INSTANCE *SataInstance,
> + IN UINT16 Port,
> + IN UINT16 PortMultiplierPort
> + );
> +
> +EFI_STATUS SiI3132IssueCommand (
> + IN SATA_SI3132_PORT *SataPort,
> + EFI_PCI_IO_PROTOCOL *PciIo,
> + IN UINT32 Timeout,
> + VOID *StatusBlock
> + );
> +
> +/**
> + * EFI SCSI Pass Thru Protocol
> + */
> +EFI_STATUS SiI3132ScsiPassThru (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun,
> + IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
> + IN EFI_EVENT Event OPTIONAL
> + );
> +
> +EFI_STATUS SiI3132GetNextTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN OUT UINT8 **Target,
> + IN OUT UINT64 *Lun
> +);
> +
> +EFI_STATUS SiI3132GetNextTargetLun2 (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun,
> + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> + );
> +
> +EFI_STATUS SiI3132ScsiBuildDevicePath (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun,
> + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
> + );
> +
> +EFI_STATUS SiI3132GetTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
> + OUT UINT8 **Target,
> + OUT UINT64 *Lun
> + );
> +
> +EFI_STATUS SiI3132ResetChannel (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
> + );
> +
> +EFI_STATUS SiI3132ResetTargetLun (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN UINT8 *Target,
> + IN UINT64 Lun
> + );
> +
> +EFI_STATUS SiI3132GetNextTarget (
> + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
> + IN OUT UINT8 **Target
> + );
> +
> #endif
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 4/6] EmbeddedPkg: SiI3132: Break out FIS command submission
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
` (2 preceding siblings ...)
2017-03-07 22:15 ` [PATCH v4 3/6] EmbeddedPkg: SiI3132: Add SCSI protocol support to header Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-17 16:31 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH v4 5/6] EmbeddedPkg: SiI3132: Cleanup device node creation Jeremy Linton
` (2 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
The existing ATA pass-through routine builds the FIS and handles
submission to the hardware. Break out the FIS submission part
so that it can be utilized by the SCSI pass-through. Also,
tighten up the error handling a bit. Starting with removal
of the ASSERTs on errors. ATAPI like SCSI uses check
conditions to indicate device state changes. So these error
paths can get exercised on CD disk change/etc. Further
we want the clamp the timeouts within a range rather than
spinning forever if the port fails to become ready.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
.../Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c | 225 +++++++++++++--------
OpenPlatformPkg | 2 +-
2 files changed, 138 insertions(+), 89 deletions(-)
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
index 2fb5fd6..601583d 100644
--- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
@@ -22,7 +22,8 @@ GetSataDevice (
IN SATA_SI3132_INSTANCE* SataInstance,
IN UINT16 Port,
IN UINT16 PortMultiplierPort
-) {
+ )
+{
LIST_ENTRY *List;
SATA_SI3132_PORT *SataPort;
SATA_SI3132_DEVICE *SataDevice;
@@ -44,6 +45,124 @@ GetSataDevice (
return NULL;
}
+UINT32
+SiI3231DeviceReady (
+ IN SATA_SI3132_PORT *SataPort,
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ UINT32 Value32;
+ UINT32 Timeout;
+ Timeout = SI_DEFAULT_TIMEOUT;
+
+ do {
+ SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_STATUS_REG, &Value32);
+ Timeout--;
+ } while (Timeout && !(Value32 & SII3132_PORT_STATUS_PORTREADY));
+ if (Timeout == 0) {
+ DEBUG ((DEBUG_WARN, "SiI3132AtaPassThru() Device not ready, try anyway\n"));
+ //Consider doing a device reset here.
+ }
+
+ return Timeout;
+}
+
+EFI_STATUS
+SiI3132IssueCommand (
+ IN SATA_SI3132_PORT *SataPort,
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT32 Timeout,
+ VOID *StatusBlock
+ )
+{
+ UINT32 IrqMask;
+ UINT32 Value32, Error;
+ UINTN EmptySlot;
+ EFI_STATUS Status;
+
+ IrqMask = (SII3132_PORT_INT_CMDCOMPL | SII3132_PORT_INT_CMDERR) << 16;
+ EmptySlot = 0;
+ SiI3231DeviceReady (SataPort, PciIo);
+ // Clear IRQ
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, IrqMask);
+
+ if (!FeaturePcdGet (PcdSataSiI3132FeatureDirectCommandIssuing)) {
+ // Indirect Command Issuance
+
+ //TODO: Find which slot is free (maybe use the Cmd FIFO)
+ //SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8),
+ (UINT32)(SataPort->PhysAddrHostPRB & 0xFFFFFFFF));
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8) + 4,
+ (UINT32)((SataPort->PhysAddrHostPRB >> 32) & 0xFFFFFFFF));
+ } else {
+ // Direct Command Issuance
+ DEBUG ((DEBUG_ERROR ,"SiI3132AtaPassThru() Untested path\n"));
+ Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
+ SataPort->RegBase + (EmptySlot * 0x80),
+ sizeof (SATA_SI3132_PRB) / 4,
+ SataPort->HostPRB);
+ ASSERT_EFI_ERROR (Status);
+
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, EmptySlot);
+ }
+
+ // Clamp the timeout range
+ if (Timeout < 1) {
+ Timeout = SI_DEFAULT_TIMEOUT;
+ } else if (Timeout > SI_DEFAULT_TIMEOUT) {
+ Timeout = SI_DEFAULT_TIMEOUT;
+ }
+
+ SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
+ while (Timeout && !(Value32 & IrqMask)) {
+ gBS->Stall (1);
+ SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
+ Timeout--;
+ }
+
+ // Fill Packet Ata Status Block
+ Status = PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
+ SataPort->RegBase + 0x08,
+ sizeof (EFI_ATA_STATUS_BLOCK) / 4,
+ StatusBlock);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n",Status, SataPort->RegBase, StatusBlock));
+ }
+
+ if (Timeout == 0) {
+ DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() Err:Timeout\n"));
+ // Flush the command, reinit port
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
+ SiI3231DeviceReady (SataPort, PciIo);
+ Status = EFI_TIMEOUT;
+
+ } else if (Value32 & (SII3132_PORT_INT_CMDERR << 16)) {
+ UINT32 Serror;
+
+ SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDERROR_REG, &Error);
+ SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SERROR_REG, &Serror);
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, Value32 & 0xFF00); //clear error bits
+
+ DEBUG ((DEBUG_INFO, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X) (STATUS: %X ERROR:%X) SERROR=%X\n",
+ Value32, Error, SataPort->HostPRB->Fis.Command,SataPort->HostPRB->Fis.Features, Serror));
+
+ // clear port status
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
+ SiI3231DeviceReady (SataPort, PciIo);
+ Status = EFI_DEVICE_ERROR;
+
+ } else if (Value32 & (SII3132_PORT_INT_CMDCOMPL << 16)) {
+ // Clear Command Complete
+ SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, SII3132_PORT_INT_CMDCOMPL << 16);
+ Status = EFI_SUCCESS;
+
+ }
+
+ return Status;
+}
+
EFI_STATUS
SiI3132AtaPassThruCommand (
IN SATA_SI3132_INSTANCE *SataSiI3132Instance,
@@ -58,18 +177,14 @@ SiI3132AtaPassThruCommand (
UINTN InDataBufferLength = 0;
EFI_PHYSICAL_ADDRESS PhysOutDataBuffer;
UINTN OutDataBufferLength;
- CONST UINTN EmptySlot = 0;
UINTN Control = PRB_CTRL_ATA;
- UINTN Protocol = 0;
- UINT32 Value32, Error, Timeout = 0;
- CONST UINT32 IrqMask = (SII3132_PORT_INT_CMDCOMPL | SII3132_PORT_INT_CMDERR) << 16;
+ UINTN Protocol = PRB_PROT_DEFAULT;
EFI_STATUS Status;
VOID* PciAllocMapping = NULL;
EFI_PCI_IO_PROTOCOL *PciIo;
PciIo = SataSiI3132Instance->PciIo;
ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
-
// Construct Si3132 PRB
switch (Packet->Protocol) {
case EFI_ATA_PASS_THRU_PROTOCOL_ATA_HARDWARE_RESET:
@@ -92,7 +207,8 @@ SiI3132AtaPassThruCommand (
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
// Fixup the size for block transfer. Following UEFI Specification, 'InTransferLength' should
// be in number of bytes. But for most data transfer commands, the value is in number of blocks
- if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
+ if ( (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) ||
+ (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DEVICE) ) {
InDataBufferLength = Packet->InTransferLength;
} else {
SataDevice = GetSataDevice (SataSiI3132Instance, SataPort->Index, PortMultiplierPort);
@@ -108,6 +224,7 @@ SiI3132AtaPassThruCommand (
Packet->InDataBuffer, &InDataBufferLength, &PhysInDataBuffer, &PciAllocMapping
);
if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SiI map() failure %d\n", Status));
return Status;
}
@@ -121,8 +238,8 @@ SiI3132AtaPassThruCommand (
CopyMem (&SataPort->HostPRB->Fis, Packet->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
// Fixup the FIS
- SataPort->HostPRB->Fis.FisType = 0x27; // Register - Host to Device FIS
- SataPort->HostPRB->Fis.Control = 1 << 7; // Is a command
+ SataPort->HostPRB->Fis.FisType = SII_FIS_REGISTER_H2D; // Register - Host to Device FIS
+ SataPort->HostPRB->Fis.Control = SII_FIS_CONTROL_CMD; // Is a command
if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
SataPort->HostPRB->Fis.Control |= PortMultiplierPort & 0xFF;
}
@@ -188,81 +305,10 @@ SiI3132AtaPassThruCommand (
SataPort->HostPRB->Control = Control;
SataPort->HostPRB->ProtocolOverride = Protocol;
- // Clear IRQ
- SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, IrqMask);
-
- if (!FeaturePcdGet (PcdSataSiI3132FeatureDirectCommandIssuing)) {
- // Indirect Command Issuance
-
- //TODO: Find which slot is free (maybe use the Cmd FIFO)
- //SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
-
- SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8),
- (UINT32)(SataPort->PhysAddrHostPRB & 0xFFFFFFFF));
- SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8) + 4,
- (UINT32)((SataPort->PhysAddrHostPRB >> 32) & 0xFFFFFFFF));
- } else {
- // Direct Command Issuance
- Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
- SataPort->RegBase + (EmptySlot * 0x80),
- sizeof (SATA_SI3132_PRB) / 4,
- SataPort->HostPRB);
- ASSERT_EFI_ERROR (Status);
-
- SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, EmptySlot);
- }
-
-#if 0
- // Could need to be implemented if we run multiple command in parallel to know which slot has been completed
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SLOTSTATUS_REG, &Value32);
- Timeout = Packet->Timeout;
- while (!Timeout && !Value32) {
- gBS->Stall (1);
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SLOTSTATUS_REG, &Value32);
- Timeout--;
- }
-#else
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
- if (!Packet->Timeout) {
- while (!(Value32 & IrqMask)) {
- gBS->Stall (1);
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
- }
- } else {
- Timeout = Packet->Timeout;
- while (Timeout && !(Value32 & IrqMask)) {
- gBS->Stall (1);
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
- Timeout--;
- }
- }
-#endif
- // Fill Packet Ata Status Block
- Status = PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
- SataPort->RegBase + 0x08,
- sizeof (EFI_ATA_STATUS_BLOCK) / 4,
- Packet->Asb);
- ASSERT_EFI_ERROR (Status);
-
-
- if ((Packet->Timeout != 0) && (Timeout == 0)) {
- DEBUG ((EFI_D_ERROR, "SiI3132AtaPassThru() Err:Timeout\n"));
- //ASSERT (0);
- return EFI_TIMEOUT;
- } else if (Value32 & (SII3132_PORT_INT_CMDERR << 16)) {
- SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDERROR_REG, &Error);
- DEBUG ((EFI_D_ERROR, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X)\n", Value32, Error));
- ASSERT (0);
- return EFI_DEVICE_ERROR;
- } else if (Value32 & (SII3132_PORT_INT_CMDCOMPL << 16)) {
- // Clear Command Complete
- SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, SII3132_PORT_INT_CMDCOMPL << 16);
-
- if (PciAllocMapping) {
- Status = PciIo->Unmap (PciIo, PciAllocMapping);
- ASSERT (!EFI_ERROR (Status));
- }
+ Status = SiI3132IssueCommand (SataPort, PciIo, Packet->Timeout, Packet->Asb);
+ if (!EFI_ERROR (Status))
+ {
// If the command was ATA_CMD_IDENTIFY_DRIVE then we need to update the BlockSize
if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
ATA_IDENTIFY_DATA *IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
@@ -279,11 +325,14 @@ SiI3132AtaPassThruCommand (
SataDevice->BlockSize = 0x200;
}
}
- return EFI_SUCCESS;
- } else {
- ASSERT (0);
- return EFI_DEVICE_ERROR;
}
+
+ if (PciAllocMapping) {
+ Status = PciIo->Unmap (PciIo, PciAllocMapping);
+ }
+
+ return Status;
+
}
/**
@@ -339,8 +388,7 @@ SiI3132AtaPassThru (
}
SataPort = SataDevice->Port;
- DEBUG ((EFI_D_INFO, "SiI3132AtaPassThru(%d,%d) : AtaCmd:0x%X Prot:%d\n", Port, PortMultiplierPort,
+ DEBUG ((DEBUG_VERBOSE, "SiI3132AtaPassThru(%p,%d,%d) : AtaCmd:0x%X Prot:%d\n", SataPort, Port, PortMultiplierPort,
Packet->Acb->AtaCommand, Packet->Protocol));
return SiI3132AtaPassThruCommand (SataSiI3132Instance, SataPort, PortMultiplierPort, Packet, Event);
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 4/6] EmbeddedPkg: SiI3132: Break out FIS command submission
2017-03-07 22:15 ` [PATCH v4 4/6] EmbeddedPkg: SiI3132: Break out FIS command submission Jeremy Linton
@ 2017-03-17 16:31 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-17 16:31 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
On Tue, Mar 07, 2017 at 04:15:09PM -0600, Jeremy Linton wrote:
> The existing ATA pass-through routine builds the FIS and handles
> submission to the hardware. Break out the FIS submission part
> so that it can be utilized by the SCSI pass-through. Also,
> tighten up the error handling a bit. Starting with removal
> of the ASSERTs on errors. ATAPI like SCSI uses check
> conditions to indicate device state changes. So these error
> paths can get exercised on CD disk change/etc. Further
> we want the clamp the timeouts within a range rather than
> spinning forever if the port fails to become ready.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> .../Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c | 225 +++++++++++++--------
> OpenPlatformPkg | 2 +-
> 2 files changed, 138 insertions(+), 89 deletions(-)
>
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> index 2fb5fd6..601583d 100644
> --- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> @@ -22,7 +22,8 @@ GetSataDevice (
> IN SATA_SI3132_INSTANCE* SataInstance,
> IN UINT16 Port,
> IN UINT16 PortMultiplierPort
> -) {
> + )
> +{
Whitespace-only change as part of functional patch.
> LIST_ENTRY *List;
> SATA_SI3132_PORT *SataPort;
> SATA_SI3132_DEVICE *SataDevice;
> @@ -44,6 +45,124 @@ GetSataDevice (
> return NULL;
> }
>
> +UINT32
> +SiI3231DeviceReady (
> + IN SATA_SI3132_PORT *SataPort,
> + IN EFI_PCI_IO_PROTOCOL *PciIo
> + )
> +{
> + UINT32 Value32;
> + UINT32 Timeout;
> + Timeout = SI_DEFAULT_TIMEOUT;
> +
> + do {
> + SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_STATUS_REG, &Value32);
> + Timeout--;
> + } while (Timeout && !(Value32 & SII3132_PORT_STATUS_PORTREADY));
I would much prefer a blank line here.
> + if (Timeout == 0) {
> + DEBUG ((DEBUG_WARN, "SiI3132AtaPassThru() Device not ready, try anyway\n"));
I guess this code this is just being moved around within the same
file, so I'll refrain from commenting on a whole bunch of stuff in
this function.
> + } else {
> + // Direct Command Issuance
> + DEBUG ((DEBUG_ERROR ,"SiI3132AtaPassThru() Untested path\n"));
> + Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
> + SataPort->RegBase + (EmptySlot * 0x80),
> + sizeof (SATA_SI3132_PRB) / 4,
> + SataPort->HostPRB);
> + ASSERT_EFI_ERROR (Status);
> +
> + SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, EmptySlot);
> + }
> +
> + // Clamp the timeout range
> + if (Timeout < 1) {
> + Timeout = SI_DEFAULT_TIMEOUT;
> + } else if (Timeout > SI_DEFAULT_TIMEOUT) {
> + Timeout = SI_DEFAULT_TIMEOUT;
> + }
> +
> + SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
> + while (Timeout && !(Value32 & IrqMask)) {
> + gBS->Stall (1);
> + SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
> + Timeout--;
> + }
> +
> + // Fill Packet Ata Status Block
> + Status = PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
> + SataPort->RegBase + 0x08,
> + sizeof (EFI_ATA_STATUS_BLOCK) / 4,
> + StatusBlock);
> +
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n",Status, SataPort->RegBase, StatusBlock));
> + }
> +
> + if (Timeout == 0) {
> + DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() Err:Timeout\n"));
> + // Flush the command, reinit port
> + SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
> + SiI3231DeviceReady (SataPort, PciIo);
> + Status = EFI_TIMEOUT;
> +
> + } else if (Value32 & (SII3132_PORT_INT_CMDERR << 16)) {
> + UINT32 Serror;
> +
> + SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDERROR_REG, &Error);
> + SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SERROR_REG, &Serror);
> + SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, Value32 & 0xFF00); //clear error bits
> +
> + DEBUG ((DEBUG_INFO, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X) (STATUS: %X ERROR:%X) SERROR=%X\n",
> + Value32, Error, SataPort->HostPRB->Fis.Command,SataPort->HostPRB->Fis.Features, Serror));
> +
> + // clear port status
> + SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
> + SiI3231DeviceReady (SataPort, PciIo);
> + Status = EFI_DEVICE_ERROR;
> +
> + } else if (Value32 & (SII3132_PORT_INT_CMDCOMPL << 16)) {
> + // Clear Command Complete
> + SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, SII3132_PORT_INT_CMDCOMPL << 16);
> + Status = EFI_SUCCESS;
> +
> + }
> +
> + return Status;
> +}
> +
> EFI_STATUS
> SiI3132AtaPassThruCommand (
> IN SATA_SI3132_INSTANCE *SataSiI3132Instance,
> @@ -58,18 +177,14 @@ SiI3132AtaPassThruCommand (
> UINTN InDataBufferLength = 0;
> EFI_PHYSICAL_ADDRESS PhysOutDataBuffer;
> UINTN OutDataBufferLength;
> - CONST UINTN EmptySlot = 0;
> UINTN Control = PRB_CTRL_ATA;
> - UINTN Protocol = 0;
> - UINT32 Value32, Error, Timeout = 0;
> - CONST UINT32 IrqMask = (SII3132_PORT_INT_CMDCOMPL | SII3132_PORT_INT_CMDERR) << 16;
> + UINTN Protocol = PRB_PROT_DEFAULT;
> EFI_STATUS Status;
> VOID* PciAllocMapping = NULL;
> EFI_PCI_IO_PROTOCOL *PciIo;
>
> PciIo = SataSiI3132Instance->PciIo;
> ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
> -
Whitespace-only change.
> // Construct Si3132 PRB
> switch (Packet->Protocol) {
> case EFI_ATA_PASS_THRU_PROTOCOL_ATA_HARDWARE_RESET:
> @@ -92,7 +207,8 @@ SiI3132AtaPassThruCommand (
> case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
> // Fixup the size for block transfer. Following UEFI Specification, 'InTransferLength' should
> // be in number of bytes. But for most data transfer commands, the value is in number of blocks
> - if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
> + if ( (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) ||
Why the redundant space after "if ("?
> + (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DEVICE) ) {
And before ") {"?
> InDataBufferLength = Packet->InTransferLength;
> } else {
> SataDevice = GetSataDevice (SataSiI3132Instance, SataPort->Index, PortMultiplierPort);
> @@ -108,6 +224,7 @@ SiI3132AtaPassThruCommand (
> Packet->InDataBuffer, &InDataBufferLength, &PhysInDataBuffer, &PciAllocMapping
> );
> if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "SiI map() failure %d\n", Status));
> return Status;
> }
>
> @@ -121,8 +238,8 @@ SiI3132AtaPassThruCommand (
> CopyMem (&SataPort->HostPRB->Fis, Packet->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
>
> // Fixup the FIS
> - SataPort->HostPRB->Fis.FisType = 0x27; // Register - Host to Device FIS
> - SataPort->HostPRB->Fis.Control = 1 << 7; // Is a command
> + SataPort->HostPRB->Fis.FisType = SII_FIS_REGISTER_H2D; // Register - Host to Device FIS
> + SataPort->HostPRB->Fis.Control = SII_FIS_CONTROL_CMD; // Is a command
> if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
> SataPort->HostPRB->Fis.Control |= PortMultiplierPort & 0xFF;
> }
> @@ -188,81 +305,10 @@ SiI3132AtaPassThruCommand (
> SataPort->HostPRB->Control = Control;
> SataPort->HostPRB->ProtocolOverride = Protocol;
>
> - // Clear IRQ
> - SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, IrqMask);
> -
> - if (!FeaturePcdGet (PcdSataSiI3132FeatureDirectCommandIssuing)) {
> - // Indirect Command Issuance
> -
> - //TODO: Find which slot is free (maybe use the Cmd FIFO)
> - //SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
> -
> - SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8),
> - (UINT32)(SataPort->PhysAddrHostPRB & 0xFFFFFFFF));
> - SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8) + 4,
> - (UINT32)((SataPort->PhysAddrHostPRB >> 32) & 0xFFFFFFFF));
> - } else {
> - // Direct Command Issuance
> - Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
> - SataPort->RegBase + (EmptySlot * 0x80),
> - sizeof (SATA_SI3132_PRB) / 4,
> - SataPort->HostPRB);
> - ASSERT_EFI_ERROR (Status);
> -
> - SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, EmptySlot);
> - }
> -
> -#if 0
> - // Could need to be implemented if we run multiple command in parallel to know which slot has been completed
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SLOTSTATUS_REG, &Value32);
> - Timeout = Packet->Timeout;
> - while (!Timeout && !Value32) {
> - gBS->Stall (1);
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_SLOTSTATUS_REG, &Value32);
> - Timeout--;
> - }
> -#else
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
> - if (!Packet->Timeout) {
> - while (!(Value32 & IrqMask)) {
> - gBS->Stall (1);
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
> - }
> - } else {
> - Timeout = Packet->Timeout;
> - while (Timeout && !(Value32 & IrqMask)) {
> - gBS->Stall (1);
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, &Value32);
> - Timeout--;
> - }
> - }
> -#endif
> - // Fill Packet Ata Status Block
> - Status = PciIo->Mem.Read (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
> - SataPort->RegBase + 0x08,
> - sizeof (EFI_ATA_STATUS_BLOCK) / 4,
> - Packet->Asb);
> - ASSERT_EFI_ERROR (Status);
> -
> -
> - if ((Packet->Timeout != 0) && (Timeout == 0)) {
> - DEBUG ((EFI_D_ERROR, "SiI3132AtaPassThru() Err:Timeout\n"));
> - //ASSERT (0);
> - return EFI_TIMEOUT;
> - } else if (Value32 & (SII3132_PORT_INT_CMDERR << 16)) {
> - SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDERROR_REG, &Error);
> - DEBUG ((EFI_D_ERROR, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X)\n", Value32, Error));
> - ASSERT (0);
> - return EFI_DEVICE_ERROR;
> - } else if (Value32 & (SII3132_PORT_INT_CMDCOMPL << 16)) {
> - // Clear Command Complete
> - SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, SII3132_PORT_INT_CMDCOMPL << 16);
> -
> - if (PciAllocMapping) {
> - Status = PciIo->Unmap (PciIo, PciAllocMapping);
> - ASSERT (!EFI_ERROR (Status));
> - }
> + Status = SiI3132IssueCommand (SataPort, PciIo, Packet->Timeout, Packet->Asb);
>
> + if (!EFI_ERROR (Status))
> + {
"{" on line before.
> // If the command was ATA_CMD_IDENTIFY_DRIVE then we need to update the BlockSize
> if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
> ATA_IDENTIFY_DATA *IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
> @@ -279,11 +325,14 @@ SiI3132AtaPassThruCommand (
> SataDevice->BlockSize = 0x200;
> }
> }
> - return EFI_SUCCESS;
> - } else {
> - ASSERT (0);
This ASSERT is not replaced in the new program flow.
Is this intentional?
> - return EFI_DEVICE_ERROR;
> }
> +
> + if (PciAllocMapping) {
> + Status = PciIo->Unmap (PciIo, PciAllocMapping);
> + }
> +
> + return Status;
> +
> }
>
> /**
> @@ -339,8 +388,7 @@ SiI3132AtaPassThru (
> }
> SataPort = SataDevice->Port;
>
> - DEBUG ((EFI_D_INFO, "SiI3132AtaPassThru(%d,%d) : AtaCmd:0x%X Prot:%d\n", Port, PortMultiplierPort,
> + DEBUG ((DEBUG_VERBOSE, "SiI3132AtaPassThru(%p,%d,%d) : AtaCmd:0x%X Prot:%d\n", SataPort, Port, PortMultiplierPort,
> Packet->Acb->AtaCommand, Packet->Protocol));
>
> return SiI3132AtaPassThruCommand (SataSiI3132Instance, SataPort, PortMultiplierPort, Packet, Event);
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 5/6] EmbeddedPkg: SiI3132: Cleanup device node creation
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
` (3 preceding siblings ...)
2017-03-07 22:15 ` [PATCH v4 4/6] EmbeddedPkg: SiI3132: Break out FIS command submission Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-17 16:37 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH v4 6/6] EmbeddedPkg: SiI3132: Enable SCSI pass-through protocol Jeremy Linton
2017-03-07 22:15 ` [PATCH] Platforms/ARM/Juno: Add " Jeremy Linton
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
There can be either ATA or ATAPI devices connected to
each SATA port. We want to detect if the device is ATA
and create a SATA_DP path or a SCSI_DP for ATAPI devices.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
.../Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c | 69 +++++++++++++---------
1 file changed, 41 insertions(+), 28 deletions(-)
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
index 601583d..ce33438 100644
--- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -61,7 +61,7 @@ SiI3231DeviceReady (
} while (Timeout && !(Value32 & SII3132_PORT_STATUS_PORTREADY));
if (Timeout == 0) {
DEBUG ((DEBUG_WARN, "SiI3132AtaPassThru() Device not ready, try anyway\n"));
- //Consider doing a device reset here.
+ // Consider doing a device reset here.
}
return Timeout;
@@ -76,7 +76,8 @@ SiI3132IssueCommand (
)
{
UINT32 IrqMask;
- UINT32 Value32, Error;
+ UINT32 Value32;
+ UINT32 Error;
UINTN EmptySlot;
EFI_STATUS Status;
@@ -89,15 +90,15 @@ SiI3132IssueCommand (
if (!FeaturePcdGet (PcdSataSiI3132FeatureDirectCommandIssuing)) {
// Indirect Command Issuance
- //TODO: Find which slot is free (maybe use the Cmd FIFO)
- //SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
+ // TODO: Find which slot is free (maybe use the Cmd FIFO)
+ // SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8),
(UINT32)(SataPort->PhysAddrHostPRB & 0xFFFFFFFF));
SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8) + 4,
(UINT32)((SataPort->PhysAddrHostPRB >> 32) & 0xFFFFFFFF));
} else {
// Direct Command Issuance
- DEBUG ((DEBUG_ERROR ,"SiI3132AtaPassThru() Untested path\n"));
+ DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() Untested path\n"));
Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
SataPort->RegBase + (EmptySlot * 0x80),
sizeof (SATA_SI3132_PRB) / 4,
@@ -128,7 +129,7 @@ SiI3132IssueCommand (
StatusBlock);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n",Status, SataPort->RegBase, StatusBlock));
+ DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n", Status, SataPort->RegBase, StatusBlock));
}
if (Timeout == 0) {
@@ -146,7 +147,7 @@ SiI3132IssueCommand (
SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, Value32 & 0xFF00); //clear error bits
DEBUG ((DEBUG_INFO, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X) (STATUS: %X ERROR:%X) SERROR=%X\n",
- Value32, Error, SataPort->HostPRB->Fis.Command,SataPort->HostPRB->Fis.Features, Serror));
+ Value32, Error, SataPort->HostPRB->Fis.Command, SataPort->HostPRB->Fis.Features, Serror));
// clear port status
SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
@@ -182,6 +183,7 @@ SiI3132AtaPassThruCommand (
EFI_STATUS Status;
VOID* PciAllocMapping = NULL;
EFI_PCI_IO_PROTOCOL *PciIo;
+ ATA_IDENTIFY_DATA *IdentifyData;
PciIo = SataSiI3132Instance->PciIo;
ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
@@ -311,7 +313,7 @@ SiI3132AtaPassThruCommand (
{
// If the command was ATA_CMD_IDENTIFY_DRIVE then we need to update the BlockSize
if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
- ATA_IDENTIFY_DATA *IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
+ IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
// Get the corresponding Block Device
SataDevice = GetSataDevice (SataSiI3132Instance, SataPort->Index, PortMultiplierPort);
@@ -446,9 +448,9 @@ SiI3132GetNextPort (
*Port = 0;
} else {
if (PrevPort < SATA_SII3132_MAXPORT) {
- *Port = PrevPort + 1;
+ *Port = PrevPort + 1;
} else {
- Status = EFI_NOT_FOUND;
+ Status = EFI_NOT_FOUND;
}
}
return Status;
@@ -521,16 +523,19 @@ SiI3132GetNextDevice (
SataPort = &(SataSiI3132Instance->Ports[Port]);
if (*PortMultiplierPort == 0xFFFF) {
+ SATA_TRACE ("SiI3132GetNextDevice() PortMultiplier");
List = SataPort->Devices.ForwardLink;
- if (List != &SataPort->Devices) {
+ if ((List != &SataPort->Devices) &&
+ (((SATA_SI3132_DEVICE*)List)->Atapi == FALSE)) {
// The list is not empty, return the first device
*PortMultiplierPort = ((SATA_SI3132_DEVICE*)List)->Index;
} else {
Status = EFI_NOT_FOUND;
}
} else {
+ SATA_TRACE ("SiI3132GetNextDevice()");
SataDevice = GetSataDevice (SataSiI3132Instance, Port, *PortMultiplierPort);
- if (SataDevice != NULL) {
+ if ((SataDevice != NULL) && (SataDevice->Atapi == FALSE)) {
// We have found the previous port multiplier, return the next one
List = SataDevice->Link.ForwardLink;
if (List != &SataPort->Devices) {
@@ -589,8 +594,6 @@ SiI3132BuildDevicePath (
SATA_SI3132_DEVICE *SataDevice;
EFI_DEVICE_PATH_PROTOCOL *SiI3132DevicePath;
- SATA_TRACE ("SiI3132BuildDevicePath()");
-
SataSiI3132Instance = INSTANCE_FROM_ATAPASSTHRU_THIS (This);
if (!SataSiI3132Instance) {
return EFI_INVALID_PARAMETER;
@@ -601,20 +604,30 @@ SiI3132BuildDevicePath (
return EFI_NOT_FOUND;
}
- SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SATA_DP, sizeof (SATA_DEVICE_PATH));
- if (SiI3132DevicePath == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ if (SataDevice->Atapi) {
+ DEBUG ((DEBUG_INFO, "SiI3132BuildDevicePath() Atapi %d:%d\n", Port, PortMultiplierPort));
+ SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SCSI_DP, sizeof (SCSI_DEVICE_PATH));
+ if (SiI3132DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ((SCSI_DEVICE_PATH*)SiI3132DevicePath)->Pun = Port;
+ ((SCSI_DEVICE_PATH*)SiI3132DevicePath)->Lun = 0;
- ((SATA_DEVICE_PATH*)SiI3132DevicePath)->HBAPortNumber = Port;
- if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
- ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = PortMultiplierPort;
} else {
- //Temp:((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;
- ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = 0;
- }
- ((SATA_DEVICE_PATH*)SiI3132DevicePath)->Lun = Port; //TODO: Search information how to define properly LUN (Logical Unit Number)
+ DEBUG ((DEBUG_VERBOSE, "SiI3132BuildDevicePath() ATA %d:%d\n", Port, PortMultiplierPort));
+ SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SATA_DP, sizeof (SATA_DEVICE_PATH));
+ if (SiI3132DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ((SATA_DEVICE_PATH*)SiI3132DevicePath)->HBAPortNumber = Port;
+ if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
+ ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = PortMultiplierPort;
+ } else {
+ ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = 0;
+ }
+ ((SATA_DEVICE_PATH*)SiI3132DevicePath)->Lun = 0; // Only support lun0 on ATA
+ }
*DevicePath = SiI3132DevicePath;
return EFI_SUCCESS;
}
@@ -680,7 +693,7 @@ SiI3132GetDevice (
return EFI_INVALID_PARAMETER;
}
- if (((SATA_DEVICE_PATH*)DevicePath)->Lun >= SATA_SII3132_MAXPORT) {
+ if (((SATA_DEVICE_PATH*)DevicePath)->HBAPortNumber >= SATA_SII3132_MAXPORT) {
return EFI_NOT_FOUND;
}
@@ -688,7 +701,7 @@ SiI3132GetDevice (
ASSERT (0); //TODO: Implement me!
return EFI_UNSUPPORTED;
} else {
- *Port = ((SATA_DEVICE_PATH*)DevicePath)->Lun;
+ *Port = ((SATA_DEVICE_PATH*)DevicePath)->HBAPortNumber;
// Return the first Sata Sevice as there should be only one directly connected
*PortMultiplierPort = ((SATA_SI3132_DEVICE*)SataSiI3132Instance->Ports[*Port].Devices.ForwardLink)->Index;
return EFI_SUCCESS;
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 5/6] EmbeddedPkg: SiI3132: Cleanup device node creation
2017-03-07 22:15 ` [PATCH v4 5/6] EmbeddedPkg: SiI3132: Cleanup device node creation Jeremy Linton
@ 2017-03-17 16:37 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-17 16:37 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
On Tue, Mar 07, 2017 at 04:15:10PM -0600, Jeremy Linton wrote:
> There can be either ATA or ATAPI devices connected to
> each SATA port. We want to detect if the device is ATA
> and create a SATA_DP path or a SCSI_DP for ATAPI devices.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> .../Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c | 69 +++++++++++++---------
> 1 file changed, 41 insertions(+), 28 deletions(-)
>
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> index 601583d..ce33438 100644
> --- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SiI3132AtaPassThru.c
> @@ -1,6 +1,6 @@
> /** @file
> *
> -* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
> +* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
> *
> * This program and the accompanying materials
> * are licensed and made available under the terms and conditions of the BSD License
> @@ -61,7 +61,7 @@ SiI3231DeviceReady (
> } while (Timeout && !(Value32 & SII3132_PORT_STATUS_PORTREADY));
> if (Timeout == 0) {
> DEBUG ((DEBUG_WARN, "SiI3132AtaPassThru() Device not ready, try anyway\n"));
> - //Consider doing a device reset here.
> + // Consider doing a device reset here.
Whitespace-only change.
> }
>
> return Timeout;
> @@ -76,7 +76,8 @@ SiI3132IssueCommand (
> )
> {
> UINT32 IrqMask;
> - UINT32 Value32, Error;
> + UINT32 Value32;
> + UINT32 Error;
Style-only change.
> UINTN EmptySlot;
> EFI_STATUS Status;
>
> @@ -89,15 +90,15 @@ SiI3132IssueCommand (
> if (!FeaturePcdGet (PcdSataSiI3132FeatureDirectCommandIssuing)) {
> // Indirect Command Issuance
>
> - //TODO: Find which slot is free (maybe use the Cmd FIFO)
> - //SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
> + // TODO: Find which slot is free (maybe use the Cmd FIFO)
> + // SATA_PORT_READ32 (SataPort->RegBase + SII3132_PORT_CMDEXECFIFO_REG, &EmptySlot);
Whitespace-only changes.
> SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8),
> (UINT32)(SataPort->PhysAddrHostPRB & 0xFFFFFFFF));
> SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CMDACTIV_REG + (EmptySlot * 8) + 4,
> (UINT32)((SataPort->PhysAddrHostPRB >> 32) & 0xFFFFFFFF));
> } else {
> // Direct Command Issuance
> - DEBUG ((DEBUG_ERROR ,"SiI3132AtaPassThru() Untested path\n"));
> + DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() Untested path\n"));
Whitespace-only change.
> Status = PciIo->Mem.Write (PciIo, EfiPciIoWidthUint32, 1, // Bar 1
> SataPort->RegBase + (EmptySlot * 0x80),
> sizeof (SATA_SI3132_PRB) / 4,
> @@ -128,7 +129,7 @@ SiI3132IssueCommand (
> StatusBlock);
>
> if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n",Status, SataPort->RegBase, StatusBlock));
> + DEBUG ((DEBUG_ERROR, "SiI3132AtaPassThru() status (%d) block %X %X\n", Status, SataPort->RegBase, StatusBlock));
Whitespace-only change.
> }
>
> if (Timeout == 0) {
> @@ -146,7 +147,7 @@ SiI3132IssueCommand (
> SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_INTSTATUS_REG, Value32 & 0xFF00); //clear error bits
>
> DEBUG ((DEBUG_INFO, "SiI3132AtaPassThru() CmdErr:0x%X (SiI3132 Err:0x%X) (STATUS: %X ERROR:%X) SERROR=%X\n",
> - Value32, Error, SataPort->HostPRB->Fis.Command,SataPort->HostPRB->Fis.Features, Serror));
> + Value32, Error, SataPort->HostPRB->Fis.Command, SataPort->HostPRB->Fis.Features, Serror));
Whitespace-only change.
>
> // clear port status
> SATA_PORT_WRITE32 (SataPort->RegBase + SII3132_PORT_CONTROLSET_REG, SII3132_PORT_CONTROL_INT);
> @@ -182,6 +183,7 @@ SiI3132AtaPassThruCommand (
> EFI_STATUS Status;
> VOID* PciAllocMapping = NULL;
> EFI_PCI_IO_PROTOCOL *PciIo;
> + ATA_IDENTIFY_DATA *IdentifyData;
>
> PciIo = SataSiI3132Instance->PciIo;
> ZeroMem (SataPort->HostPRB, sizeof (SATA_SI3132_PRB));
> @@ -311,7 +313,7 @@ SiI3132AtaPassThruCommand (
> {
> // If the command was ATA_CMD_IDENTIFY_DRIVE then we need to update the BlockSize
> if (Packet->Acb->AtaCommand == ATA_CMD_IDENTIFY_DRIVE) {
> - ATA_IDENTIFY_DATA *IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
> + IdentifyData = (ATA_IDENTIFY_DATA*)Packet->InDataBuffer;
>
> // Get the corresponding Block Device
> SataDevice = GetSataDevice (SataSiI3132Instance, SataPort->Index, PortMultiplierPort);
> @@ -446,9 +448,9 @@ SiI3132GetNextPort (
> *Port = 0;
> } else {
> if (PrevPort < SATA_SII3132_MAXPORT) {
> - *Port = PrevPort + 1;
> + *Port = PrevPort + 1;
> } else {
> - Status = EFI_NOT_FOUND;
> + Status = EFI_NOT_FOUND;
Whitespace-only changes.
> }
> }
> return Status;
> @@ -521,16 +523,19 @@ SiI3132GetNextDevice (
> SataPort = &(SataSiI3132Instance->Ports[Port]);
>
> if (*PortMultiplierPort == 0xFFFF) {
> + SATA_TRACE ("SiI3132GetNextDevice() PortMultiplier");
> List = SataPort->Devices.ForwardLink;
> - if (List != &SataPort->Devices) {
> + if ((List != &SataPort->Devices) &&
> + (((SATA_SI3132_DEVICE*)List)->Atapi == FALSE)) {
> // The list is not empty, return the first device
> *PortMultiplierPort = ((SATA_SI3132_DEVICE*)List)->Index;
> } else {
> Status = EFI_NOT_FOUND;
> }
> } else {
> + SATA_TRACE ("SiI3132GetNextDevice()");
> SataDevice = GetSataDevice (SataSiI3132Instance, Port, *PortMultiplierPort);
> - if (SataDevice != NULL) {
> + if ((SataDevice != NULL) && (SataDevice->Atapi == FALSE)) {
> // We have found the previous port multiplier, return the next one
> List = SataDevice->Link.ForwardLink;
> if (List != &SataPort->Devices) {
> @@ -589,8 +594,6 @@ SiI3132BuildDevicePath (
> SATA_SI3132_DEVICE *SataDevice;
> EFI_DEVICE_PATH_PROTOCOL *SiI3132DevicePath;
>
> - SATA_TRACE ("SiI3132BuildDevicePath()");
> -
> SataSiI3132Instance = INSTANCE_FROM_ATAPASSTHRU_THIS (This);
> if (!SataSiI3132Instance) {
> return EFI_INVALID_PARAMETER;
> @@ -601,20 +604,30 @@ SiI3132BuildDevicePath (
> return EFI_NOT_FOUND;
> }
>
> - SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SATA_DP, sizeof (SATA_DEVICE_PATH));
> - if (SiI3132DevicePath == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> + if (SataDevice->Atapi) {
> + DEBUG ((DEBUG_INFO, "SiI3132BuildDevicePath() Atapi %d:%d\n", Port, PortMultiplierPort));
> + SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SCSI_DP, sizeof (SCSI_DEVICE_PATH));
> + if (SiI3132DevicePath == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + ((SCSI_DEVICE_PATH*)SiI3132DevicePath)->Pun = Port;
> + ((SCSI_DEVICE_PATH*)SiI3132DevicePath)->Lun = 0;
>
> - ((SATA_DEVICE_PATH*)SiI3132DevicePath)->HBAPortNumber = Port;
> - if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
> - ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = PortMultiplierPort;
> } else {
> - //Temp:((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;
> - ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = 0;
> - }
> - ((SATA_DEVICE_PATH*)SiI3132DevicePath)->Lun = Port; //TODO: Search information how to define properly LUN (Logical Unit Number)
> + DEBUG ((DEBUG_VERBOSE, "SiI3132BuildDevicePath() ATA %d:%d\n", Port, PortMultiplierPort));
> + SiI3132DevicePath = CreateDeviceNode (MESSAGING_DEVICE_PATH, MSG_SATA_DP, sizeof (SATA_DEVICE_PATH));
> + if (SiI3132DevicePath == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
>
> + ((SATA_DEVICE_PATH*)SiI3132DevicePath)->HBAPortNumber = Port;
> + if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
> + ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = PortMultiplierPort;
> + } else {
> + ((SATA_DEVICE_PATH*)SiI3132DevicePath)->PortMultiplierPortNumber = 0;
> + }
> + ((SATA_DEVICE_PATH*)SiI3132DevicePath)->Lun = 0; // Only support lun0 on ATA
> + }
> *DevicePath = SiI3132DevicePath;
> return EFI_SUCCESS;
> }
> @@ -680,7 +693,7 @@ SiI3132GetDevice (
> return EFI_INVALID_PARAMETER;
> }
>
> - if (((SATA_DEVICE_PATH*)DevicePath)->Lun >= SATA_SII3132_MAXPORT) {
> + if (((SATA_DEVICE_PATH*)DevicePath)->HBAPortNumber >= SATA_SII3132_MAXPORT) {
> return EFI_NOT_FOUND;
> }
>
> @@ -688,7 +701,7 @@ SiI3132GetDevice (
> ASSERT (0); //TODO: Implement me!
> return EFI_UNSUPPORTED;
> } else {
> - *Port = ((SATA_DEVICE_PATH*)DevicePath)->Lun;
> + *Port = ((SATA_DEVICE_PATH*)DevicePath)->HBAPortNumber;
> // Return the first Sata Sevice as there should be only one directly connected
> *PortMultiplierPort = ((SATA_SI3132_DEVICE*)SataSiI3132Instance->Ports[*Port].Devices.ForwardLink)->Index;
> return EFI_SUCCESS;
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 6/6] EmbeddedPkg: SiI3132: Enable SCSI pass-through protocol
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
` (4 preceding siblings ...)
2017-03-07 22:15 ` [PATCH v4 5/6] EmbeddedPkg: SiI3132: Cleanup device node creation Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
2017-03-17 16:40 ` Leif Lindholm
2017-03-07 22:15 ` [PATCH] Platforms/ARM/Juno: Add " Jeremy Linton
6 siblings, 1 reply; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
Now that everything is in place, lets export the protocol,
build the module, and remove the ATAPI unsupported flags.
Now when we detect an ATAPI device on a port we flag it
as such.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c | 52 ++++++++++++++--------
.../Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf | 2 +
2 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
index f494655..b98231c 100644
--- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
@@ -1,7 +1,7 @@
/** @file
* PCIe Sata support for the Silicon Image I3132
*
-* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -16,6 +16,7 @@
#include "SataSiI3132.h"
#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Atapi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
@@ -88,7 +89,6 @@ SataSiI3132Constructor (
)
{
SATA_SI3132_INSTANCE *Instance;
- EFI_ATA_PASS_THRU_MODE *AtaPassThruMode;
if (!SataSiI3132Instance) {
return EFI_INVALID_PARAMETER;
@@ -102,16 +102,15 @@ SataSiI3132Constructor (
Instance->Signature = SATA_SII3132_SIGNATURE;
Instance->PciIo = PciIo;
- AtaPassThruMode = (EFI_ATA_PASS_THRU_MODE*)AllocatePool (sizeof (EFI_ATA_PASS_THRU_MODE));
- AtaPassThruMode->Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
- AtaPassThruMode->IoAlign = 0x1000;
+ Instance->AtaPassThruMode.Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
+ Instance->AtaPassThruMode.IoAlign = 0x4;
// Initialize SiI3132 ports
SataSiI3132PortConstructor (Instance, 0);
SataSiI3132PortConstructor (Instance, 1);
// Set ATA Pass Thru Protocol
- Instance->AtaPassThruProtocol.Mode = AtaPassThruMode;
+ Instance->AtaPassThruProtocol.Mode = &Instance->AtaPassThruMode;
Instance->AtaPassThruProtocol.PassThru = SiI3132AtaPassThru;
Instance->AtaPassThruProtocol.GetNextPort = SiI3132GetNextPort;
Instance->AtaPassThruProtocol.GetNextDevice = SiI3132GetNextDevice;
@@ -120,6 +119,20 @@ SataSiI3132Constructor (
Instance->AtaPassThruProtocol.ResetPort = SiI3132ResetPort;
Instance->AtaPassThruProtocol.ResetDevice = SiI3132ResetDevice;
+ Instance->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
+ EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
+ Instance->ExtScsiPassThruMode.IoAlign = 0x4;
+
+ // Set SCSI Pass Thru Protocol
+ Instance->ExtScsiPassThru.Mode = &Instance->ExtScsiPassThruMode;
+ Instance->ExtScsiPassThru.PassThru = SiI3132ScsiPassThru;
+ Instance->ExtScsiPassThru.GetNextTargetLun = SiI3132GetNextTargetLun;
+ Instance->ExtScsiPassThru.BuildDevicePath = SiI3132ScsiBuildDevicePath;
+ Instance->ExtScsiPassThru.GetTargetLun = SiI3132GetTargetLun;
+ Instance->ExtScsiPassThru.ResetChannel = SiI3132ResetChannel;
+ Instance->ExtScsiPassThru.ResetTargetLun = SiI3132ResetTargetLun;
+ Instance->ExtScsiPassThru.GetNextTarget = SiI3132GetNextTarget;
+
*SataSiI3132Instance = Instance;
return EFI_SUCCESS;
@@ -165,7 +178,9 @@ SataSiI3132PortInitialization (
UINT32 Signature;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL* PciIo;
+ BOOLEAN Atapi;
+ Atapi = FALSE;
Status = SiI3132HwResetPort (Port);
if (EFI_ERROR (Status)) {
return Status;
@@ -177,33 +192,33 @@ SataSiI3132PortInitialization (
Status = SATA_PORT_READ32 (Port->RegBase + SII3132_PORT_SSTATUS_REG, &Value32);
if (!EFI_ERROR (Status) && (Value32 & 0x3)) {
// Do a soft reset to see if it is a port multiplier
- SATA_TRACE ("SataSiI3132PortInitialization: soft reset - it is a port multiplier\n");
+ SATA_TRACE ("SataSiI3132PortInitialization: soft reset - is it a port multiplier?\n");
Status = SiI3132SoftResetCommand (Port, &Signature);
if (!EFI_ERROR (Status)) {
if (Signature == SII3132_PORT_SIGNATURE_PMP) {
- SATA_TRACE ("SataSiI3132PortInitialization(): a Port Multiplier is present");
+ DEBUG ((DEBUG_ERROR, "SataSiI3132PortInitialization(): a Port Multiplier is present"));
if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
ASSERT (0); // Not supported yet
} else {
return EFI_UNSUPPORTED;
}
} else if (Signature == SII3132_PORT_SIGNATURE_ATAPI) {
- ASSERT (0); // Not supported yet
SATA_TRACE ("SataSiI3132PortInitialization(): an ATAPI device is present");
- return EFI_UNSUPPORTED;
+ Atapi = TRUE;
} else if (Signature == SII3132_PORT_SIGNATURE_ATA) {
SATA_TRACE ("SataSiI3132PortInitialization(): an ATA device is present");
} else {
- SATA_TRACE ("SataSiI3132PortInitialization(): Present device unknown!");
+ DEBUG ((DEBUG_ERROR, "SataSiI3132PortInitialization(): Present device unknown!"));
ASSERT (0); // Not supported
return EFI_UNSUPPORTED;
}
// Create Device
Device = (SATA_SI3132_DEVICE*)AllocatePool (sizeof (SATA_SI3132_DEVICE));
- Device->Index = Port->Index; //TODO: Could need to be fixed when SATA Port Multiplier support
+ Device->Index = 0; //TODO: When port multiplers are supported this is the multiplier index
Device->Port = Port;
Device->BlockSize = 0;
+ Device->Atapi = Atapi;
// Attached the device to the Sata Port
InsertTailList (&Port->Devices, &Device->Link);
@@ -432,13 +447,12 @@ SataSiI3132DriverBindingStart (
return Status;
}
- // Install Ata Pass Thru Protocol
- Status = gBS->InstallProtocolInterface (
- &Controller,
- &gEfiAtaPassThruProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &(SataSiI3132Instance->AtaPassThruProtocol)
- );
+ Status = gBS->InstallMultipleProtocolInterfaces (&Controller,
+ &gEfiAtaPassThruProtocolGuid,
+ &(SataSiI3132Instance->AtaPassThruProtocol),
+ &gEfiExtScsiPassThruProtocolGuid,
+ &(SataSiI3132Instance->ExtScsiPassThru),
+ NULL);
if (EFI_ERROR (Status)) {
goto FREE_POOL;
}
diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
index 69aaab3..eb6e2bd 100644
--- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
+++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
@@ -35,10 +35,12 @@
SataSiI3132.c
ComponentName.c
SiI3132AtaPassThru.c
+ SiI3132ScsiPassThru.c
[Protocols]
gEfiPciIoProtocolGuid # Consumed
gEfiAtaPassThruProtocolGuid # Produced
+ gEfiExtScsiPassThruProtocolGuid # Produced
[Pcd]
gEmbeddedTokenSpaceGuid.PcdSataSiI3132FeaturePMPSupport
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v4 6/6] EmbeddedPkg: SiI3132: Enable SCSI pass-through protocol
2017-03-07 22:15 ` [PATCH v4 6/6] EmbeddedPkg: SiI3132: Enable SCSI pass-through protocol Jeremy Linton
@ 2017-03-17 16:40 ` Leif Lindholm
0 siblings, 0 replies; 17+ messages in thread
From: Leif Lindholm @ 2017-03-17 16:40 UTC (permalink / raw)
To: Jeremy Linton; +Cc: edk2-devel, ryan.harkin, linaro-uefi, ard.biesheuvel
On Tue, Mar 07, 2017 at 04:15:11PM -0600, Jeremy Linton wrote:
> Now that everything is in place, lets export the protocol,
> build the module, and remove the ATAPI unsupported flags.
> Now when we detect an ATAPI device on a port we flag it
> as such.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c | 52 ++++++++++++++--------
> .../Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf | 2 +
> 2 files changed, 35 insertions(+), 19 deletions(-)
>
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
> index f494655..b98231c 100644
> --- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132.c
> @@ -1,7 +1,7 @@
> /** @file
> * PCIe Sata support for the Silicon Image I3132
> *
> -* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
> +* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
> *
> * This program and the accompanying materials
> * are licensed and made available under the terms and conditions of the BSD License
> @@ -16,6 +16,7 @@
> #include "SataSiI3132.h"
>
> #include <IndustryStandard/Acpi10.h>
> +#include <IndustryStandard/Atapi.h>
>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/UefiBootServicesTableLib.h>
> @@ -88,7 +89,6 @@ SataSiI3132Constructor (
> )
> {
> SATA_SI3132_INSTANCE *Instance;
> - EFI_ATA_PASS_THRU_MODE *AtaPassThruMode;
>
> if (!SataSiI3132Instance) {
> return EFI_INVALID_PARAMETER;
> @@ -102,16 +102,15 @@ SataSiI3132Constructor (
> Instance->Signature = SATA_SII3132_SIGNATURE;
> Instance->PciIo = PciIo;
>
> - AtaPassThruMode = (EFI_ATA_PASS_THRU_MODE*)AllocatePool (sizeof (EFI_ATA_PASS_THRU_MODE));
> - AtaPassThruMode->Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
> - AtaPassThruMode->IoAlign = 0x1000;
> + Instance->AtaPassThruMode.Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
> + Instance->AtaPassThruMode.IoAlign = 0x4;
Why 0x4? Could we have a #define with a descriptive name instead?
>
> // Initialize SiI3132 ports
> SataSiI3132PortConstructor (Instance, 0);
> SataSiI3132PortConstructor (Instance, 1);
>
> // Set ATA Pass Thru Protocol
> - Instance->AtaPassThruProtocol.Mode = AtaPassThruMode;
> + Instance->AtaPassThruProtocol.Mode = &Instance->AtaPassThruMode;
> Instance->AtaPassThruProtocol.PassThru = SiI3132AtaPassThru;
> Instance->AtaPassThruProtocol.GetNextPort = SiI3132GetNextPort;
> Instance->AtaPassThruProtocol.GetNextDevice = SiI3132GetNextDevice;
> @@ -120,6 +119,20 @@ SataSiI3132Constructor (
> Instance->AtaPassThruProtocol.ResetPort = SiI3132ResetPort;
> Instance->AtaPassThruProtocol.ResetDevice = SiI3132ResetDevice;
>
> + Instance->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
> + EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
> + Instance->ExtScsiPassThruMode.IoAlign = 0x4;
And here?
> +
> + // Set SCSI Pass Thru Protocol
> + Instance->ExtScsiPassThru.Mode = &Instance->ExtScsiPassThruMode;
> + Instance->ExtScsiPassThru.PassThru = SiI3132ScsiPassThru;
> + Instance->ExtScsiPassThru.GetNextTargetLun = SiI3132GetNextTargetLun;
> + Instance->ExtScsiPassThru.BuildDevicePath = SiI3132ScsiBuildDevicePath;
> + Instance->ExtScsiPassThru.GetTargetLun = SiI3132GetTargetLun;
> + Instance->ExtScsiPassThru.ResetChannel = SiI3132ResetChannel;
> + Instance->ExtScsiPassThru.ResetTargetLun = SiI3132ResetTargetLun;
> + Instance->ExtScsiPassThru.GetNextTarget = SiI3132GetNextTarget;
> +
> *SataSiI3132Instance = Instance;
>
> return EFI_SUCCESS;
> @@ -165,7 +178,9 @@ SataSiI3132PortInitialization (
> UINT32 Signature;
> EFI_STATUS Status;
> EFI_PCI_IO_PROTOCOL* PciIo;
> + BOOLEAN Atapi;
>
> + Atapi = FALSE;
> Status = SiI3132HwResetPort (Port);
> if (EFI_ERROR (Status)) {
> return Status;
> @@ -177,33 +192,33 @@ SataSiI3132PortInitialization (
> Status = SATA_PORT_READ32 (Port->RegBase + SII3132_PORT_SSTATUS_REG, &Value32);
> if (!EFI_ERROR (Status) && (Value32 & 0x3)) {
> // Do a soft reset to see if it is a port multiplier
> - SATA_TRACE ("SataSiI3132PortInitialization: soft reset - it is a port multiplier\n");
> + SATA_TRACE ("SataSiI3132PortInitialization: soft reset - is it a port multiplier?\n");
> Status = SiI3132SoftResetCommand (Port, &Signature);
> if (!EFI_ERROR (Status)) {
> if (Signature == SII3132_PORT_SIGNATURE_PMP) {
> - SATA_TRACE ("SataSiI3132PortInitialization(): a Port Multiplier is present");
> + DEBUG ((DEBUG_ERROR, "SataSiI3132PortInitialization(): a Port Multiplier is present"));
What's the dignificance of switching from SATA_TRACE to DEBUG?
Upgrading the verbosity?
> if (FeaturePcdGet (PcdSataSiI3132FeaturePMPSupport)) {
> ASSERT (0); // Not supported yet
> } else {
> return EFI_UNSUPPORTED;
> }
> } else if (Signature == SII3132_PORT_SIGNATURE_ATAPI) {
> - ASSERT (0); // Not supported yet
> SATA_TRACE ("SataSiI3132PortInitialization(): an ATAPI device is present");
> - return EFI_UNSUPPORTED;
> + Atapi = TRUE;
> } else if (Signature == SII3132_PORT_SIGNATURE_ATA) {
> SATA_TRACE ("SataSiI3132PortInitialization(): an ATA device is present");
> } else {
> - SATA_TRACE ("SataSiI3132PortInitialization(): Present device unknown!");
> + DEBUG ((DEBUG_ERROR, "SataSiI3132PortInitialization(): Present device unknown!"));
> ASSERT (0); // Not supported
> return EFI_UNSUPPORTED;
> }
>
> // Create Device
> Device = (SATA_SI3132_DEVICE*)AllocatePool (sizeof (SATA_SI3132_DEVICE));
> - Device->Index = Port->Index; //TODO: Could need to be fixed when SATA Port Multiplier support
> + Device->Index = 0; //TODO: When port multiplers are supported this is the multiplier index
> Device->Port = Port;
> Device->BlockSize = 0;
> + Device->Atapi = Atapi;
>
> // Attached the device to the Sata Port
> InsertTailList (&Port->Devices, &Device->Link);
> @@ -432,13 +447,12 @@ SataSiI3132DriverBindingStart (
> return Status;
> }
>
> - // Install Ata Pass Thru Protocol
> - Status = gBS->InstallProtocolInterface (
> - &Controller,
> - &gEfiAtaPassThruProtocolGuid,
> - EFI_NATIVE_INTERFACE,
> - &(SataSiI3132Instance->AtaPassThruProtocol)
> - );
> + Status = gBS->InstallMultipleProtocolInterfaces (&Controller,
> + &gEfiAtaPassThruProtocolGuid,
> + &(SataSiI3132Instance->AtaPassThruProtocol),
> + &gEfiExtScsiPassThruProtocolGuid,
> + &(SataSiI3132Instance->ExtScsiPassThru),
> + NULL);
> if (EFI_ERROR (Status)) {
> goto FREE_POOL;
> }
> diff --git a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
> index 69aaab3..eb6e2bd 100644
> --- a/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
> +++ b/EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
> @@ -35,10 +35,12 @@
> SataSiI3132.c
> ComponentName.c
> SiI3132AtaPassThru.c
> + SiI3132ScsiPassThru.c
>
> [Protocols]
> gEfiPciIoProtocolGuid # Consumed
> gEfiAtaPassThruProtocolGuid # Produced
> + gEfiExtScsiPassThruProtocolGuid # Produced
>
> [Pcd]
> gEmbeddedTokenSpaceGuid.PcdSataSiI3132FeaturePMPSupport
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] Platforms/ARM/Juno: Add SCSI pass-through protocol
2017-03-07 22:15 [PATCH v4 0/6] ATAPI support on SiI SATA adapter Jeremy Linton
` (5 preceding siblings ...)
2017-03-07 22:15 ` [PATCH v4 6/6] EmbeddedPkg: SiI3132: Enable SCSI pass-through protocol Jeremy Linton
@ 2017-03-07 22:15 ` Jeremy Linton
6 siblings, 0 replies; 17+ messages in thread
From: Jeremy Linton @ 2017-03-07 22:15 UTC (permalink / raw)
To: edk2-devel
Cc: leif.lindholm, ryan.harkin, linaro-uefi, ard.biesheuvel,
Jeremy Linton
Now that the SiI adapter supports ATAPI, add the SCSI
pass-through protocol.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
Platforms/ARM/Juno/ArmJuno.dsc | 3 +++
Platforms/ARM/Juno/ArmJuno.fdf | 2 ++
2 files changed, 5 insertions(+)
diff --git a/Platforms/ARM/Juno/ArmJuno.dsc b/Platforms/ARM/Juno/ArmJuno.dsc
index 4080c0b..1e3e551 100644
--- a/Platforms/ARM/Juno/ArmJuno.dsc
+++ b/Platforms/ARM/Juno/ArmJuno.dsc
@@ -49,6 +49,7 @@
# USB Requirements
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[LibraryClasses.common.SEC]
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
@@ -285,6 +286,8 @@
# SATA Controller
#
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
#
diff --git a/Platforms/ARM/Juno/ArmJuno.fdf b/Platforms/ARM/Juno/ArmJuno.fdf
index beee7af..b20367e 100644
--- a/Platforms/ARM/Juno/ArmJuno.fdf
+++ b/Platforms/ARM/Juno/ArmJuno.fdf
@@ -166,6 +166,8 @@ FvNameGuid = B73FE497-B92E-416e-8326-45AD0D270092
# SATA Controller
#
INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
INF EmbeddedPkg/Drivers/SataSiI3132Dxe/SataSiI3132Dxe.inf
#
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread