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