OvmfPkg/MptScsiDxe: Install stubbed EXT_SCSI_PASS_THRU
[mirror_edk2.git] / OvmfPkg / MptScsiDxe / MptScsi.c
CommitLineData
feec20b2
NL
1/** @file\r
2\r
3 This driver produces Extended SCSI Pass Thru Protocol instances for\r
4 LSI Fusion MPT SCSI devices.\r
5\r
6 Copyright (C) 2020, Oracle and/or its affiliates.\r
7\r
8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9\r
10**/\r
11\r
f4707442
NL
12#include <IndustryStandard/FusionMptScsi.h>\r
13#include <IndustryStandard/Pci.h>\r
a53e5b41
NL
14#include <Library/DebugLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
f4707442 16#include <Library/UefiBootServicesTableLib.h>\r
ad8f2d6b 17#include <Library/UefiLib.h>\r
f4707442 18#include <Protocol/PciIo.h>\r
a53e5b41 19#include <Protocol/ScsiPassThruExt.h>\r
feec20b2
NL
20#include <Uefi/UefiSpec.h>\r
21\r
ad8f2d6b
NL
22//\r
23// Higher versions will be used before lower, 0x10-0xffffffef is the version\r
24// range for IVH (Indie Hardware Vendors)\r
25//\r
26#define MPT_SCSI_BINDING_VERSION 0x10\r
27\r
a53e5b41
NL
28//\r
29// Runtime Structures\r
30//\r
31\r
32#define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S')\r
33typedef struct {\r
34 UINT32 Signature;\r
35 EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;\r
36 EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;\r
37} MPT_SCSI_DEV;\r
38\r
39#define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \\r
40 CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE)\r
41\r
42//\r
43// Ext SCSI Pass Thru\r
44//\r
45\r
46STATIC\r
47EFI_STATUS\r
48EFIAPI\r
49MptScsiPassThru (\r
50 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
51 IN UINT8 *Target,\r
52 IN UINT64 Lun,\r
53 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,\r
54 IN EFI_EVENT Event OPTIONAL\r
55 )\r
56{\r
57 return EFI_UNSUPPORTED;\r
58}\r
59\r
60STATIC\r
61EFI_STATUS\r
62EFIAPI\r
63MptScsiGetNextTargetLun (\r
64 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
65 IN OUT UINT8 **Target,\r
66 IN OUT UINT64 *Lun\r
67 )\r
68{\r
69 return EFI_UNSUPPORTED;\r
70}\r
71\r
72STATIC\r
73EFI_STATUS\r
74EFIAPI\r
75MptScsiGetNextTarget (\r
76 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
77 IN OUT UINT8 **Target\r
78 )\r
79{\r
80 return EFI_UNSUPPORTED;\r
81}\r
82\r
83STATIC\r
84EFI_STATUS\r
85EFIAPI\r
86MptScsiBuildDevicePath (\r
87 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
88 IN UINT8 *Target,\r
89 IN UINT64 Lun,\r
90 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
91 )\r
92{\r
93 return EFI_UNSUPPORTED;\r
94}\r
95\r
96STATIC\r
97EFI_STATUS\r
98EFIAPI\r
99MptScsiGetTargetLun (\r
100 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
101 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
102 OUT UINT8 **Target,\r
103 OUT UINT64 *Lun\r
104 )\r
105{\r
106 return EFI_UNSUPPORTED;\r
107}\r
108\r
109STATIC\r
110EFI_STATUS\r
111EFIAPI\r
112MptScsiResetChannel (\r
113 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This\r
114 )\r
115{\r
116 return EFI_UNSUPPORTED;\r
117}\r
118\r
119STATIC\r
120EFI_STATUS\r
121EFIAPI\r
122MptScsiResetTargetLun (\r
123 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
124 IN UINT8 *Target,\r
125 IN UINT64 Lun\r
126 )\r
127{\r
128 return EFI_UNSUPPORTED;\r
129}\r
130\r
ad8f2d6b
NL
131//\r
132// Driver Binding\r
133//\r
134\r
135STATIC\r
136EFI_STATUS\r
137EFIAPI\r
138MptScsiControllerSupported (\r
139 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
140 IN EFI_HANDLE ControllerHandle,\r
141 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
142 )\r
143{\r
f4707442
NL
144 EFI_STATUS Status;\r
145 EFI_PCI_IO_PROTOCOL *PciIo;\r
146 PCI_TYPE00 Pci;\r
147\r
148 Status = gBS->OpenProtocol (\r
149 ControllerHandle,\r
150 &gEfiPciIoProtocolGuid,\r
151 (VOID **)&PciIo,\r
152 This->DriverBindingHandle,\r
153 ControllerHandle,\r
154 EFI_OPEN_PROTOCOL_BY_DRIVER\r
155 );\r
156 if (EFI_ERROR (Status)) {\r
157 return Status;\r
158 }\r
159\r
160 Status = PciIo->Pci.Read (\r
161 PciIo,\r
162 EfiPciIoWidthUint32,\r
163 0,\r
164 sizeof (Pci) / sizeof (UINT32),\r
165 &Pci\r
166 );\r
167 if (EFI_ERROR (Status)) {\r
168 goto Done;\r
169 }\r
170\r
171 if (Pci.Hdr.VendorId == LSI_LOGIC_PCI_VENDOR_ID &&\r
172 (Pci.Hdr.DeviceId == LSI_53C1030_PCI_DEVICE_ID ||\r
173 Pci.Hdr.DeviceId == LSI_SAS1068_PCI_DEVICE_ID ||\r
174 Pci.Hdr.DeviceId == LSI_SAS1068E_PCI_DEVICE_ID)) {\r
175 Status = EFI_SUCCESS;\r
176 } else {\r
177 Status = EFI_UNSUPPORTED;\r
178 }\r
179\r
180Done:\r
181 gBS->CloseProtocol (\r
182 ControllerHandle,\r
183 &gEfiPciIoProtocolGuid,\r
184 This->DriverBindingHandle,\r
185 ControllerHandle\r
186 );\r
187 return Status;\r
ad8f2d6b
NL
188}\r
189\r
190STATIC\r
191EFI_STATUS\r
192EFIAPI\r
193MptScsiControllerStart (\r
194 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
195 IN EFI_HANDLE ControllerHandle,\r
196 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
197 )\r
198{\r
a53e5b41
NL
199 EFI_STATUS Status;\r
200 MPT_SCSI_DEV *Dev;\r
201\r
202 Dev = AllocateZeroPool (sizeof (*Dev));\r
203 if (Dev == NULL) {\r
204 return EFI_OUT_OF_RESOURCES;\r
205 }\r
206\r
207 Dev->Signature = MPT_SCSI_DEV_SIGNATURE;\r
208\r
209 //\r
210 // Host adapter channel, doesn't exist\r
211 //\r
212 Dev->PassThruMode.AdapterId = MAX_UINT32;\r
213 Dev->PassThruMode.Attributes =\r
214 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |\r
215 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
216\r
217 Dev->PassThru.Mode = &Dev->PassThruMode;\r
218 Dev->PassThru.PassThru = &MptScsiPassThru;\r
219 Dev->PassThru.GetNextTargetLun = &MptScsiGetNextTargetLun;\r
220 Dev->PassThru.BuildDevicePath = &MptScsiBuildDevicePath;\r
221 Dev->PassThru.GetTargetLun = &MptScsiGetTargetLun;\r
222 Dev->PassThru.ResetChannel = &MptScsiResetChannel;\r
223 Dev->PassThru.ResetTargetLun = &MptScsiResetTargetLun;\r
224 Dev->PassThru.GetNextTarget = &MptScsiGetNextTarget;\r
225\r
226 Status = gBS->InstallProtocolInterface (\r
227 &ControllerHandle,\r
228 &gEfiExtScsiPassThruProtocolGuid,\r
229 EFI_NATIVE_INTERFACE,\r
230 &Dev->PassThru\r
231 );\r
232 if (EFI_ERROR (Status)) {\r
233 goto FreePool;\r
234 }\r
235\r
236 return EFI_SUCCESS;\r
237\r
238FreePool:\r
239 FreePool (Dev);\r
240\r
241 return Status;\r
ad8f2d6b
NL
242}\r
243\r
244STATIC\r
245EFI_STATUS\r
246EFIAPI\r
247MptScsiControllerStop (\r
248 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
249 IN EFI_HANDLE ControllerHandle,\r
250 IN UINTN NumberOfChildren,\r
251 IN EFI_HANDLE *ChildHandleBuffer\r
252 )\r
253{\r
a53e5b41
NL
254 EFI_STATUS Status;\r
255 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
256 MPT_SCSI_DEV *Dev;\r
257\r
258 Status = gBS->OpenProtocol (\r
259 ControllerHandle,\r
260 &gEfiExtScsiPassThruProtocolGuid,\r
261 (VOID **)&PassThru,\r
262 This->DriverBindingHandle,\r
263 ControllerHandle,\r
264 EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only\r
265 );\r
266 if (EFI_ERROR (Status)) {\r
267 return Status;\r
268 }\r
269\r
270 Dev = MPT_SCSI_FROM_PASS_THRU (PassThru);\r
271\r
272 Status = gBS->UninstallProtocolInterface (\r
273 ControllerHandle,\r
274 &gEfiExtScsiPassThruProtocolGuid,\r
275 &Dev->PassThru\r
276 );\r
277 if (EFI_ERROR (Status)) {\r
278 return Status;\r
279 }\r
280\r
281 FreePool (Dev);\r
282\r
283 return Status;\r
ad8f2d6b
NL
284}\r
285\r
286STATIC\r
287EFI_DRIVER_BINDING_PROTOCOL mMptScsiDriverBinding = {\r
288 &MptScsiControllerSupported,\r
289 &MptScsiControllerStart,\r
290 &MptScsiControllerStop,\r
291 MPT_SCSI_BINDING_VERSION,\r
292 NULL, // ImageHandle, filled by EfiLibInstallDriverBindingComponentName2\r
293 NULL, // DriverBindingHandle, filled as well\r
294};\r
295\r
be7fcaa1
NL
296//\r
297// Component Name\r
298//\r
299\r
300STATIC\r
301EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {\r
302 { "eng;en", L"LSI Fusion MPT SCSI Driver" },\r
303 { NULL, NULL }\r
304};\r
305\r
306STATIC\r
307EFI_COMPONENT_NAME_PROTOCOL mComponentName;\r
308\r
309EFI_STATUS\r
310EFIAPI\r
311MptScsiGetDriverName (\r
312 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
313 IN CHAR8 *Language,\r
314 OUT CHAR16 **DriverName\r
315 )\r
316{\r
317 return LookupUnicodeString2 (\r
318 Language,\r
319 This->SupportedLanguages,\r
320 mDriverNameTable,\r
321 DriverName,\r
322 (BOOLEAN)(This == &mComponentName) // Iso639Language\r
323 );\r
324}\r
325\r
326EFI_STATUS\r
327EFIAPI\r
328MptScsiGetDeviceName (\r
329 IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
330 IN EFI_HANDLE DeviceHandle,\r
331 IN EFI_HANDLE ChildHandle,\r
332 IN CHAR8 *Language,\r
333 OUT CHAR16 **ControllerName\r
334 )\r
335{\r
336 return EFI_UNSUPPORTED;\r
337}\r
338\r
339STATIC\r
340EFI_COMPONENT_NAME_PROTOCOL mComponentName = {\r
341 &MptScsiGetDriverName,\r
342 &MptScsiGetDeviceName,\r
343 "eng" // SupportedLanguages, ISO 639-2 language codes\r
344};\r
345\r
346STATIC\r
347EFI_COMPONENT_NAME2_PROTOCOL mComponentName2 = {\r
348 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &MptScsiGetDriverName,\r
349 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &MptScsiGetDeviceName,\r
350 "en" // SupportedLanguages, RFC 4646 language codes\r
351};\r
352\r
feec20b2
NL
353//\r
354// Entry Point\r
355//\r
356\r
357EFI_STATUS\r
358EFIAPI\r
359MptScsiEntryPoint (\r
360 IN EFI_HANDLE ImageHandle,\r
361 IN EFI_SYSTEM_TABLE *SystemTable\r
362 )\r
363{\r
ad8f2d6b
NL
364 return EfiLibInstallDriverBindingComponentName2 (\r
365 ImageHandle,\r
366 SystemTable,\r
367 &mMptScsiDriverBinding,\r
368 ImageHandle, // The handle to install onto\r
be7fcaa1
NL
369 &mComponentName,\r
370 &mComponentName2\r
ad8f2d6b 371 );\r
feec20b2 372}\r