3 This driver produces Extended SCSI Pass Thru Protocol instances for
6 Copyright (C) 2020, Oracle and/or its affiliates.
8 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <IndustryStandard/Pci.h>
13 #include <IndustryStandard/PvScsi.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16 #include <Library/UefiLib.h>
17 #include <Protocol/PciIo.h>
18 #include <Uefi/UefiSpec.h>
23 // Higher versions will be used before lower, 0x10-0xffffffef is the version
24 // range for IHV (Indie Hardware Vendors)
26 #define PVSCSI_BINDING_VERSION 0x10
36 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
39 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
,
40 IN EFI_EVENT Event OPTIONAL
43 return EFI_UNSUPPORTED
;
49 PvScsiGetNextTargetLun (
50 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
51 IN OUT UINT8
**Target
,
55 return EFI_UNSUPPORTED
;
61 PvScsiBuildDevicePath (
62 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
65 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
68 return EFI_UNSUPPORTED
;
75 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
76 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
81 return EFI_UNSUPPORTED
;
88 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
91 return EFI_UNSUPPORTED
;
97 PvScsiResetTargetLun (
98 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
103 return EFI_UNSUPPORTED
;
109 PvScsiGetNextTarget (
110 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*This
,
111 IN OUT UINT8
**Target
114 return EFI_UNSUPPORTED
;
120 IN OUT PVSCSI_DEV
*Dev
124 // Populate the exported interface's attributes
126 Dev
->PassThru
.Mode
= &Dev
->PassThruMode
;
127 Dev
->PassThru
.PassThru
= &PvScsiPassThru
;
128 Dev
->PassThru
.GetNextTargetLun
= &PvScsiGetNextTargetLun
;
129 Dev
->PassThru
.BuildDevicePath
= &PvScsiBuildDevicePath
;
130 Dev
->PassThru
.GetTargetLun
= &PvScsiGetTargetLun
;
131 Dev
->PassThru
.ResetChannel
= &PvScsiResetChannel
;
132 Dev
->PassThru
.ResetTargetLun
= &PvScsiResetTargetLun
;
133 Dev
->PassThru
.GetNextTarget
= &PvScsiGetNextTarget
;
136 // AdapterId is a target for which no handle will be created during bus scan.
137 // Prevent any conflict with real devices.
139 Dev
->PassThruMode
.AdapterId
= MAX_UINT32
;
142 // Set both physical and logical attributes for non-RAID SCSI channel
144 Dev
->PassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
|
145 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
148 // No restriction on transfer buffer alignment
150 Dev
->PassThruMode
.IoAlign
= 0;
158 IN OUT PVSCSI_DEV
*Dev
161 // Currently nothing to do here
171 PvScsiDriverBindingSupported (
172 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
173 IN EFI_HANDLE ControllerHandle
,
174 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
178 EFI_PCI_IO_PROTOCOL
*PciIo
;
181 Status
= gBS
->OpenProtocol (
183 &gEfiPciIoProtocolGuid
,
185 This
->DriverBindingHandle
,
187 EFI_OPEN_PROTOCOL_BY_DRIVER
189 if (EFI_ERROR (Status
)) {
193 Status
= PciIo
->Pci
.Read (
197 sizeof (Pci
) / sizeof (UINT32
),
200 if (EFI_ERROR (Status
)) {
204 if ((Pci
.Hdr
.VendorId
!= PCI_VENDOR_ID_VMWARE
) ||
205 (Pci
.Hdr
.DeviceId
!= PCI_DEVICE_ID_VMWARE_PVSCSI
)) {
206 Status
= EFI_UNSUPPORTED
;
210 Status
= EFI_SUCCESS
;
215 &gEfiPciIoProtocolGuid
,
216 This
->DriverBindingHandle
,
226 PvScsiDriverBindingStart (
227 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
228 IN EFI_HANDLE ControllerHandle
,
229 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
235 Dev
= (PVSCSI_DEV
*) AllocateZeroPool (sizeof (*Dev
));
237 return EFI_OUT_OF_RESOURCES
;
240 Status
= PvScsiInit (Dev
);
241 if (EFI_ERROR (Status
)) {
246 // Setup complete, attempt to export the driver instance's PassThru interface
248 Dev
->Signature
= PVSCSI_SIG
;
249 Status
= gBS
->InstallProtocolInterface (
251 &gEfiExtScsiPassThruProtocolGuid
,
252 EFI_NATIVE_INTERFACE
,
255 if (EFI_ERROR (Status
)) {
273 PvScsiDriverBindingStop (
274 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
275 IN EFI_HANDLE ControllerHandle
,
276 IN UINTN NumberOfChildren
,
277 IN EFI_HANDLE
*ChildHandleBuffer
281 EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*PassThru
;
284 Status
= gBS
->OpenProtocol (
286 &gEfiExtScsiPassThruProtocolGuid
,
288 This
->DriverBindingHandle
,
290 EFI_OPEN_PROTOCOL_GET_PROTOCOL
// Lookup only
292 if (EFI_ERROR (Status
)) {
296 Dev
= PVSCSI_FROM_PASS_THRU (PassThru
);
298 Status
= gBS
->UninstallProtocolInterface (
300 &gEfiExtScsiPassThruProtocolGuid
,
303 if (EFI_ERROR (Status
)) {
314 STATIC EFI_DRIVER_BINDING_PROTOCOL mPvScsiDriverBinding
= {
315 &PvScsiDriverBindingSupported
,
316 &PvScsiDriverBindingStart
,
317 &PvScsiDriverBindingStop
,
318 PVSCSI_BINDING_VERSION
,
319 NULL
, // ImageHandle, filled by EfiLibInstallDriverBindingComponentName2()
320 NULL
// DriverBindingHandle, filled as well
327 STATIC EFI_UNICODE_STRING_TABLE mDriverNameTable
[] = {
328 { "eng;en", L
"PVSCSI Host Driver" },
332 STATIC EFI_COMPONENT_NAME_PROTOCOL mComponentName
;
337 PvScsiGetDriverName (
338 IN EFI_COMPONENT_NAME_PROTOCOL
*This
,
340 OUT CHAR16
**DriverName
343 return LookupUnicodeString2 (
345 This
->SupportedLanguages
,
348 (BOOLEAN
)(This
== &mComponentName
) // Iso639Language
355 PvScsiGetDeviceName (
356 IN EFI_COMPONENT_NAME_PROTOCOL
*This
,
357 IN EFI_HANDLE DeviceHandle
,
358 IN EFI_HANDLE ChildHandle
,
360 OUT CHAR16
**ControllerName
363 return EFI_UNSUPPORTED
;
366 STATIC EFI_COMPONENT_NAME_PROTOCOL mComponentName
= {
367 &PvScsiGetDriverName
,
368 &PvScsiGetDeviceName
,
369 "eng" // SupportedLanguages, ISO 639-2 language codes
372 STATIC EFI_COMPONENT_NAME2_PROTOCOL mComponentName2
= {
373 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME
) &PvScsiGetDriverName
,
374 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME
) &PvScsiGetDeviceName
,
375 "en" // SupportedLanguages, RFC 4646 language codes
385 IN EFI_HANDLE ImageHandle
,
386 IN EFI_SYSTEM_TABLE
*SystemTable
389 return EfiLibInstallDriverBindingComponentName2 (
392 &mPvScsiDriverBinding
,