]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/LsiScsiDxe/LsiScsi.c
OvmfPkg/LsiScsiDxe: Probe PCI devices and look for LsiScsi
[mirror_edk2.git] / OvmfPkg / LsiScsiDxe / LsiScsi.c
1 /** @file
2
3 This driver produces Extended SCSI Pass Thru Protocol instances for
4 LSI 53C895A SCSI devices.
5
6 Copyright (C) 2020, SUSE LLC.
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include <IndustryStandard/LsiScsi.h>
13 #include <IndustryStandard/Pci.h>
14 #include <Library/UefiBootServicesTableLib.h>
15 #include <Library/UefiLib.h>
16 #include <Protocol/PciIo.h>
17 #include <Protocol/PciRootBridgeIo.h>
18 #include <Uefi/UefiSpec.h>
19
20 #include "LsiScsi.h"
21
22 //
23 // Probe, start and stop functions of this driver, called by the DXE core for
24 // specific devices.
25 //
26 // The following specifications document these interfaces:
27 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
28 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
29 //
30
31 EFI_STATUS
32 EFIAPI
33 LsiScsiControllerSupported (
34 IN EFI_DRIVER_BINDING_PROTOCOL *This,
35 IN EFI_HANDLE ControllerHandle,
36 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
37 )
38 {
39 EFI_STATUS Status;
40 EFI_PCI_IO_PROTOCOL *PciIo;
41 PCI_TYPE00 Pci;
42
43 Status = gBS->OpenProtocol (
44 ControllerHandle,
45 &gEfiPciIoProtocolGuid,
46 (VOID **)&PciIo,
47 This->DriverBindingHandle,
48 ControllerHandle,
49 EFI_OPEN_PROTOCOL_BY_DRIVER
50 );
51 if (EFI_ERROR (Status)) {
52 return Status;
53 }
54
55 Status = PciIo->Pci.Read (
56 PciIo,
57 EfiPciIoWidthUint32,
58 0,
59 sizeof (Pci) / sizeof (UINT32),
60 &Pci
61 );
62 if (EFI_ERROR (Status)) {
63 goto Done;
64 }
65
66 if (Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID &&
67 Pci.Hdr.DeviceId == LSI_53C895A_PCI_DEVICE_ID) {
68 Status = EFI_SUCCESS;
69 } else {
70 Status = EFI_UNSUPPORTED;
71 }
72
73 Done:
74 gBS->CloseProtocol (
75 ControllerHandle,
76 &gEfiPciIoProtocolGuid,
77 This->DriverBindingHandle,
78 ControllerHandle
79 );
80 return Status;
81 }
82
83 EFI_STATUS
84 EFIAPI
85 LsiScsiControllerStart (
86 IN EFI_DRIVER_BINDING_PROTOCOL *This,
87 IN EFI_HANDLE ControllerHandle,
88 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
89 )
90 {
91 return EFI_SUCCESS;
92 }
93
94 EFI_STATUS
95 EFIAPI
96 LsiScsiControllerStop (
97 IN EFI_DRIVER_BINDING_PROTOCOL *This,
98 IN EFI_HANDLE ControllerHandle,
99 IN UINTN NumberOfChildren,
100 IN EFI_HANDLE *ChildHandleBuffer
101 )
102 {
103 return EFI_SUCCESS;
104 }
105
106 //
107 // The static object that groups the Supported() (ie. probe), Start() and
108 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
109 // C, 10.1 EFI Driver Binding Protocol.
110 //
111 STATIC
112 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
113 &LsiScsiControllerSupported,
114 &LsiScsiControllerStart,
115 &LsiScsiControllerStop,
116 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
117 NULL, // ImageHandle, to be overwritten by
118 // EfiLibInstallDriverBindingComponentName2() in LsiScsiEntryPoint()
119 NULL // DriverBindingHandle, ditto
120 };
121
122
123 //
124 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
125 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
126 // in English, for display on standard console devices. This is recommended for
127 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
128 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
129 //
130 // Device type names ("LSI 53C895A SCSI Controller") are not formatted because
131 // the driver supports only that device type. Therefore the driver name
132 // suffices for unambiguous identification.
133 //
134
135 STATIC
136 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
137 { "eng;en", L"LSI 53C895A SCSI Controller Driver" },
138 { NULL, NULL }
139 };
140
141 STATIC
142 EFI_COMPONENT_NAME_PROTOCOL gComponentName;
143
144 EFI_STATUS
145 EFIAPI
146 LsiScsiGetDriverName (
147 IN EFI_COMPONENT_NAME_PROTOCOL *This,
148 IN CHAR8 *Language,
149 OUT CHAR16 **DriverName
150 )
151 {
152 return LookupUnicodeString2 (
153 Language,
154 This->SupportedLanguages,
155 mDriverNameTable,
156 DriverName,
157 (BOOLEAN)(This == &gComponentName) // Iso639Language
158 );
159 }
160
161 EFI_STATUS
162 EFIAPI
163 LsiScsiGetDeviceName (
164 IN EFI_COMPONENT_NAME_PROTOCOL *This,
165 IN EFI_HANDLE DeviceHandle,
166 IN EFI_HANDLE ChildHandle,
167 IN CHAR8 *Language,
168 OUT CHAR16 **ControllerName
169 )
170 {
171 return EFI_UNSUPPORTED;
172 }
173
174 STATIC
175 EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
176 &LsiScsiGetDriverName,
177 &LsiScsiGetDeviceName,
178 "eng" // SupportedLanguages, ISO 639-2 language codes
179 };
180
181 STATIC
182 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
183 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &LsiScsiGetDriverName,
184 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &LsiScsiGetDeviceName,
185 "en" // SupportedLanguages, RFC 4646 language codes
186 };
187
188 //
189 // Entry point of this driver
190 //
191 EFI_STATUS
192 EFIAPI
193 LsiScsiEntryPoint (
194 IN EFI_HANDLE ImageHandle,
195 IN EFI_SYSTEM_TABLE *SystemTable
196 )
197 {
198 return EfiLibInstallDriverBindingComponentName2 (
199 ImageHandle,
200 SystemTable,
201 &gDriverBinding,
202 ImageHandle, // The handle to install onto
203 &gComponentName,
204 &gComponentName2
205 );
206 }