]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/LsiScsiDxe/LsiScsi.c
OvmfPkg/LsiScsiDxe: Install stubbed EXT_SCSI_PASS_THRU
[mirror_edk2.git] / OvmfPkg / LsiScsiDxe / LsiScsi.c
CommitLineData
e94d04a0
GL
1/** @file\r
2\r
3 This driver produces Extended SCSI Pass Thru Protocol instances for\r
4 LSI 53C895A SCSI devices.\r
5\r
6 Copyright (C) 2020, SUSE LLC.\r
7\r
8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9\r
10**/\r
11\r
79f802a5
GL
12#include <IndustryStandard/LsiScsi.h>\r
13#include <IndustryStandard/Pci.h>\r
23d982e2
GL
14#include <Library/BaseLib.h>\r
15#include <Library/BaseMemoryLib.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
79f802a5 18#include <Library/UefiBootServicesTableLib.h>\r
5e6b870a 19#include <Library/UefiLib.h>\r
79f802a5
GL
20#include <Protocol/PciIo.h>\r
21#include <Protocol/PciRootBridgeIo.h>\r
23d982e2 22#include <Protocol/ScsiPassThruExt.h>\r
e94d04a0
GL
23#include <Uefi/UefiSpec.h>\r
24\r
5e6b870a
GL
25#include "LsiScsi.h"\r
26\r
23d982e2
GL
27//\r
28// The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL\r
29// for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C,\r
30// sections\r
31// - 14.1 SCSI Driver Model Overview,\r
32// - 14.7 Extended SCSI Pass Thru Protocol.\r
33//\r
34\r
35EFI_STATUS\r
36EFIAPI\r
37LsiScsiPassThru (\r
38 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
39 IN UINT8 *Target,\r
40 IN UINT64 Lun,\r
41 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,\r
42 IN EFI_EVENT Event OPTIONAL\r
43 )\r
44{\r
45 return EFI_UNSUPPORTED;\r
46}\r
47\r
48EFI_STATUS\r
49EFIAPI\r
50LsiScsiGetNextTargetLun (\r
51 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
52 IN OUT UINT8 **TargetPointer,\r
53 IN OUT UINT64 *Lun\r
54 )\r
55{\r
56 return EFI_NOT_FOUND;\r
57}\r
58\r
59EFI_STATUS\r
60EFIAPI\r
61LsiScsiBuildDevicePath (\r
62 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
63 IN UINT8 *Target,\r
64 IN UINT64 Lun,\r
65 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
66 )\r
67{\r
68 return EFI_NOT_FOUND;\r
69}\r
70\r
71EFI_STATUS\r
72EFIAPI\r
73LsiScsiGetTargetLun (\r
74 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
75 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
76 OUT UINT8 **TargetPointer,\r
77 OUT UINT64 *Lun\r
78 )\r
79{\r
80 return EFI_UNSUPPORTED;\r
81}\r
82\r
83EFI_STATUS\r
84EFIAPI\r
85LsiScsiResetChannel (\r
86 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This\r
87 )\r
88{\r
89 return EFI_UNSUPPORTED;\r
90}\r
91\r
92EFI_STATUS\r
93EFIAPI\r
94LsiScsiResetTargetLun (\r
95 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
96 IN UINT8 *Target,\r
97 IN UINT64 Lun\r
98 )\r
99{\r
100 return EFI_UNSUPPORTED;\r
101}\r
102\r
103EFI_STATUS\r
104EFIAPI\r
105LsiScsiGetNextTarget (\r
106 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
107 IN OUT UINT8 **TargetPointer\r
108 )\r
109{\r
110 return EFI_NOT_FOUND;\r
111}\r
112\r
5e6b870a
GL
113//\r
114// Probe, start and stop functions of this driver, called by the DXE core for\r
115// specific devices.\r
116//\r
117// The following specifications document these interfaces:\r
118// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol\r
119// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol\r
120//\r
121\r
122EFI_STATUS\r
123EFIAPI\r
124LsiScsiControllerSupported (\r
125 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
126 IN EFI_HANDLE ControllerHandle,\r
127 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
128 )\r
129{\r
79f802a5
GL
130 EFI_STATUS Status;\r
131 EFI_PCI_IO_PROTOCOL *PciIo;\r
132 PCI_TYPE00 Pci;\r
133\r
134 Status = gBS->OpenProtocol (\r
135 ControllerHandle,\r
136 &gEfiPciIoProtocolGuid,\r
137 (VOID **)&PciIo,\r
138 This->DriverBindingHandle,\r
139 ControllerHandle,\r
140 EFI_OPEN_PROTOCOL_BY_DRIVER\r
141 );\r
142 if (EFI_ERROR (Status)) {\r
143 return Status;\r
144 }\r
145\r
146 Status = PciIo->Pci.Read (\r
147 PciIo,\r
148 EfiPciIoWidthUint32,\r
149 0,\r
150 sizeof (Pci) / sizeof (UINT32),\r
151 &Pci\r
152 );\r
153 if (EFI_ERROR (Status)) {\r
154 goto Done;\r
155 }\r
156\r
157 if (Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID &&\r
158 Pci.Hdr.DeviceId == LSI_53C895A_PCI_DEVICE_ID) {\r
159 Status = EFI_SUCCESS;\r
160 } else {\r
161 Status = EFI_UNSUPPORTED;\r
162 }\r
163\r
164Done:\r
165 gBS->CloseProtocol (\r
166 ControllerHandle,\r
167 &gEfiPciIoProtocolGuid,\r
168 This->DriverBindingHandle,\r
169 ControllerHandle\r
170 );\r
171 return Status;\r
5e6b870a
GL
172}\r
173\r
174EFI_STATUS\r
175EFIAPI\r
176LsiScsiControllerStart (\r
177 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
178 IN EFI_HANDLE ControllerHandle,\r
179 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
180 )\r
181{\r
23d982e2
GL
182 EFI_STATUS Status;\r
183 LSI_SCSI_DEV *Dev;\r
184\r
185 Dev = AllocateZeroPool (sizeof (*Dev));\r
186 if (Dev == NULL) {\r
187 return EFI_OUT_OF_RESOURCES;\r
188 }\r
189\r
190 Dev->Signature = LSI_SCSI_DEV_SIGNATURE;\r
191\r
192 //\r
193 // Host adapter channel, doesn't exist\r
194 //\r
195 Dev->PassThruMode.AdapterId = MAX_UINT32;\r
196 Dev->PassThruMode.Attributes =\r
197 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |\r
198 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
199\r
200 Dev->PassThru.Mode = &Dev->PassThruMode;\r
201 Dev->PassThru.PassThru = &LsiScsiPassThru;\r
202 Dev->PassThru.GetNextTargetLun = &LsiScsiGetNextTargetLun;\r
203 Dev->PassThru.BuildDevicePath = &LsiScsiBuildDevicePath;\r
204 Dev->PassThru.GetTargetLun = &LsiScsiGetTargetLun;\r
205 Dev->PassThru.ResetChannel = &LsiScsiResetChannel;\r
206 Dev->PassThru.ResetTargetLun = &LsiScsiResetTargetLun;\r
207 Dev->PassThru.GetNextTarget = &LsiScsiGetNextTarget;\r
208\r
209 Status = gBS->InstallProtocolInterface (\r
210 &ControllerHandle,\r
211 &gEfiExtScsiPassThruProtocolGuid,\r
212 EFI_NATIVE_INTERFACE,\r
213 &Dev->PassThru\r
214 );\r
215 if (EFI_ERROR (Status)) {\r
216 goto FreePool;\r
217 }\r
218\r
5e6b870a 219 return EFI_SUCCESS;\r
23d982e2
GL
220\r
221FreePool:\r
222 FreePool (Dev);\r
223\r
224 return Status;\r
5e6b870a
GL
225}\r
226\r
227EFI_STATUS\r
228EFIAPI\r
229LsiScsiControllerStop (\r
230 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
231 IN EFI_HANDLE ControllerHandle,\r
232 IN UINTN NumberOfChildren,\r
233 IN EFI_HANDLE *ChildHandleBuffer\r
234 )\r
235{\r
23d982e2
GL
236 EFI_STATUS Status;\r
237 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
238 LSI_SCSI_DEV *Dev;\r
239\r
240 Status = gBS->OpenProtocol (\r
241 ControllerHandle,\r
242 &gEfiExtScsiPassThruProtocolGuid,\r
243 (VOID **)&PassThru,\r
244 This->DriverBindingHandle,\r
245 ControllerHandle,\r
246 EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only\r
247 );\r
248 if (EFI_ERROR (Status)) {\r
249 return Status;\r
250 }\r
251\r
252 Dev = LSI_SCSI_FROM_PASS_THRU (PassThru);\r
253\r
254 Status = gBS->UninstallProtocolInterface (\r
255 ControllerHandle,\r
256 &gEfiExtScsiPassThruProtocolGuid,\r
257 &Dev->PassThru\r
258 );\r
259 if (EFI_ERROR (Status)) {\r
260 return Status;\r
261 }\r
262\r
263 FreePool (Dev);\r
264\r
265 return Status;\r
5e6b870a
GL
266}\r
267\r
268//\r
269// The static object that groups the Supported() (ie. probe), Start() and\r
270// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata\r
271// C, 10.1 EFI Driver Binding Protocol.\r
272//\r
273STATIC\r
274EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
275 &LsiScsiControllerSupported,\r
276 &LsiScsiControllerStart,\r
277 &LsiScsiControllerStop,\r
278 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers\r
279 NULL, // ImageHandle, to be overwritten by\r
280 // EfiLibInstallDriverBindingComponentName2() in LsiScsiEntryPoint()\r
281 NULL // DriverBindingHandle, ditto\r
282};\r
283\r
284\r
386ca8ab
GL
285//\r
286// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and\r
287// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name\r
288// in English, for display on standard console devices. This is recommended for\r
289// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's\r
290// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.\r
291//\r
292// Device type names ("LSI 53C895A SCSI Controller") are not formatted because\r
293// the driver supports only that device type. Therefore the driver name\r
294// suffices for unambiguous identification.\r
295//\r
296\r
297STATIC\r
298EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {\r
299 { "eng;en", L"LSI 53C895A SCSI Controller Driver" },\r
300 { NULL, NULL }\r
301};\r
302\r
303STATIC\r
304EFI_COMPONENT_NAME_PROTOCOL gComponentName;\r
305\r
306EFI_STATUS\r
307EFIAPI\r
308LsiScsiGetDriverName (\r
309 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
310 IN CHAR8 *Language,\r
311 OUT CHAR16 **DriverName\r
312 )\r
313{\r
314 return LookupUnicodeString2 (\r
315 Language,\r
316 This->SupportedLanguages,\r
317 mDriverNameTable,\r
318 DriverName,\r
319 (BOOLEAN)(This == &gComponentName) // Iso639Language\r
320 );\r
321}\r
322\r
323EFI_STATUS\r
324EFIAPI\r
325LsiScsiGetDeviceName (\r
326 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
327 IN EFI_HANDLE DeviceHandle,\r
328 IN EFI_HANDLE ChildHandle,\r
329 IN CHAR8 *Language,\r
330 OUT CHAR16 **ControllerName\r
331 )\r
332{\r
333 return EFI_UNSUPPORTED;\r
334}\r
335\r
336STATIC\r
337EFI_COMPONENT_NAME_PROTOCOL gComponentName = {\r
338 &LsiScsiGetDriverName,\r
339 &LsiScsiGetDeviceName,\r
340 "eng" // SupportedLanguages, ISO 639-2 language codes\r
341};\r
342\r
343STATIC\r
344EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {\r
345 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &LsiScsiGetDriverName,\r
346 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &LsiScsiGetDeviceName,\r
347 "en" // SupportedLanguages, RFC 4646 language codes\r
348};\r
349\r
e94d04a0
GL
350//\r
351// Entry point of this driver\r
352//\r
353EFI_STATUS\r
354EFIAPI\r
355LsiScsiEntryPoint (\r
356 IN EFI_HANDLE ImageHandle,\r
357 IN EFI_SYSTEM_TABLE *SystemTable\r
358 )\r
359{\r
5e6b870a
GL
360 return EfiLibInstallDriverBindingComponentName2 (\r
361 ImageHandle,\r
362 SystemTable,\r
363 &gDriverBinding,\r
364 ImageHandle, // The handle to install onto\r
386ca8ab
GL
365 &gComponentName,\r
366 &gComponentName2\r
5e6b870a 367 );\r
e94d04a0 368}\r