OvmfPkg/LsiScsiDxe: Open PciIo protocol and initialize the device

Open PciIo protocol and use it to initialize the device. The
initialization of LSI 53C895A is simple: just set the SRST bit in
Interrupt Status Zero register to reset the device.

v2:
  - Use the BITx macros for the bit constants
  - Add the closing of PciIo protocol in LsiScsiControllerStop()

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Message-Id: <20200717061130.8881-8-glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Gary Lin 2020-07-17 14:11:26 +08:00 committed by mergify[bot]
parent 12d99b8f23
commit 8d6193902f
3 changed files with 159 additions and 1 deletions

View File

@ -17,4 +17,25 @@
#define LSI_LOGIC_PCI_VENDOR_ID 0x1000 #define LSI_LOGIC_PCI_VENDOR_ID 0x1000
#define LSI_53C895A_PCI_DEVICE_ID 0x0012 #define LSI_53C895A_PCI_DEVICE_ID 0x0012
//
// LSI 53C895A Registers
//
#define LSI_REG_DSTAT 0x0C
#define LSI_REG_ISTAT0 0x14
#define LSI_REG_DSP 0x2C
#define LSI_REG_SIST0 0x42
#define LSI_REG_SIST1 0x43
//
// The status bits for Interrupt Status Zero (ISTAT0)
//
#define LSI_ISTAT0_DIP BIT0
#define LSI_ISTAT0_SIP BIT1
#define LSI_ISTAT0_INTF BIT2
#define LSI_ISTAT0_CON BIT3
#define LSI_ISTAT0_SEM BIT4
#define LSI_ISTAT0_SIGP BIT5
#define LSI_ISTAT0_SRST BIT6
#define LSI_ISTAT0_ABRT BIT7
#endif // _LSI_SCSI_H_ #endif // _LSI_SCSI_H_

View File

@ -25,6 +25,33 @@
#include "LsiScsi.h" #include "LsiScsi.h"
STATIC
EFI_STATUS
Out8 (
IN LSI_SCSI_DEV *Dev,
IN UINT32 Addr,
IN UINT8 Data
)
{
return Dev->PciIo->Io.Write (
Dev->PciIo,
EfiPciIoWidthUint8,
PCI_BAR_IDX0,
Addr,
1,
&Data
);
}
STATIC
EFI_STATUS
LsiScsiReset (
IN LSI_SCSI_DEV *Dev
)
{
return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST);
}
// //
// The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL // The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL
// for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C, // for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C,
@ -243,6 +270,21 @@ LsiScsiGetNextTarget (
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
STATIC
VOID
EFIAPI
LsiScsiExitBoot (
IN EFI_EVENT Event,
IN VOID *Context
)
{
LSI_SCSI_DEV *Dev;
Dev = Context;
DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
LsiScsiReset (Dev);
}
// //
// Probe, start and stop functions of this driver, called by the DXE core for // Probe, start and stop functions of this driver, called by the DXE core for
// specific devices. // specific devices.
@ -333,6 +375,58 @@ LsiScsiControllerStart (
Dev->MaxTarget = PcdGet8 (PcdLsiScsiMaxTargetLimit); Dev->MaxTarget = PcdGet8 (PcdLsiScsiMaxTargetLimit);
Dev->MaxLun = PcdGet8 (PcdLsiScsiMaxLunLimit); Dev->MaxLun = PcdGet8 (PcdLsiScsiMaxLunLimit);
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiPciIoProtocolGuid,
(VOID **)&Dev->PciIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto FreePool;
}
Status = Dev->PciIo->Attributes (
Dev->PciIo,
EfiPciIoAttributeOperationGet,
0,
&Dev->OrigPciAttrs
);
if (EFI_ERROR (Status)) {
goto CloseProtocol;
}
//
// Enable I/O Space & Bus-Mastering
//
Status = Dev->PciIo->Attributes (
Dev->PciIo,
EfiPciIoAttributeOperationEnable,
(EFI_PCI_IO_ATTRIBUTE_IO |
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
NULL
);
if (EFI_ERROR (Status)) {
goto CloseProtocol;
}
Status = LsiScsiReset (Dev);
if (EFI_ERROR (Status)) {
goto RestoreAttributes;
}
Status = gBS->CreateEvent (
EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_CALLBACK,
&LsiScsiExitBoot,
Dev,
&Dev->ExitBoot
);
if (EFI_ERROR (Status)) {
goto UninitDev;
}
// //
// Host adapter channel, doesn't exist // Host adapter channel, doesn't exist
// //
@ -357,11 +451,33 @@ LsiScsiControllerStart (
&Dev->PassThru &Dev->PassThru
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto FreePool; goto CloseExitBoot;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
CloseExitBoot:
gBS->CloseEvent (Dev->ExitBoot);
UninitDev:
LsiScsiReset (Dev);
RestoreAttributes:
Dev->PciIo->Attributes (
Dev->PciIo,
EfiPciIoAttributeOperationSet,
Dev->OrigPciAttrs,
NULL
);
CloseProtocol:
gBS->CloseProtocol (
ControllerHandle,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
FreePool: FreePool:
FreePool (Dev); FreePool (Dev);
@ -404,6 +520,24 @@ LsiScsiControllerStop (
return Status; return Status;
} }
gBS->CloseEvent (Dev->ExitBoot);
LsiScsiReset (Dev);
Dev->PciIo->Attributes (
Dev->PciIo,
EfiPciIoAttributeOperationSet,
Dev->OrigPciAttrs,
NULL
);
gBS->CloseProtocol (
ControllerHandle,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
FreePool (Dev); FreePool (Dev);
return Status; return Status;

View File

@ -14,6 +14,9 @@
typedef struct { typedef struct {
UINT32 Signature; UINT32 Signature;
UINT64 OrigPciAttrs;
EFI_EVENT ExitBoot;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 MaxTarget; UINT8 MaxTarget;
UINT8 MaxLun; UINT8 MaxLun;
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode; EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;