]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioFsDxe/DriverBinding.c
OvmfPkg/VirtioFsDxe: implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / DriverBinding.c
1 /** @file
2 Provide EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on virtio-fs devices.
3
4 Copyright (C) 2020, Red Hat, Inc.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8
9 #include <Library/BaseLib.h> // AsciiStrCmp()
10 #include <Library/MemoryAllocationLib.h> // AllocatePool()
11 #include <Library/UefiBootServicesTableLib.h> // gBS
12 #include <Protocol/ComponentName2.h> // EFI_COMPONENT_NAME2_PROTOCOL
13 #include <Protocol/DriverBinding.h> // EFI_DRIVER_BINDING_PROTOCOL
14
15 #include "VirtioFsDxe.h"
16
17 //
18 // UEFI Driver Model protocol instances.
19 //
20 STATIC EFI_DRIVER_BINDING_PROTOCOL mDriverBinding;
21 STATIC EFI_COMPONENT_NAME2_PROTOCOL mComponentName2;
22
23 //
24 // UEFI Driver Model protocol member functions.
25 //
26 EFI_STATUS
27 EFIAPI
28 VirtioFsBindingSupported (
29 IN EFI_DRIVER_BINDING_PROTOCOL *This,
30 IN EFI_HANDLE ControllerHandle,
31 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
32 )
33 {
34 EFI_STATUS Status;
35 VIRTIO_DEVICE_PROTOCOL *Virtio;
36 EFI_STATUS CloseStatus;
37
38 Status = gBS->OpenProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
39 (VOID **)&Virtio, This->DriverBindingHandle,
40 ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
41 if (EFI_ERROR (Status)) {
42 return Status;
43 }
44
45 if (Virtio->SubSystemDeviceId != VIRTIO_SUBSYSTEM_FILESYSTEM) {
46 Status = EFI_UNSUPPORTED;
47 }
48
49 CloseStatus = gBS->CloseProtocol (ControllerHandle,
50 &gVirtioDeviceProtocolGuid, This->DriverBindingHandle,
51 ControllerHandle);
52 ASSERT_EFI_ERROR (CloseStatus);
53
54 return Status;
55 }
56
57 EFI_STATUS
58 EFIAPI
59 VirtioFsBindingStart (
60 IN EFI_DRIVER_BINDING_PROTOCOL *This,
61 IN EFI_HANDLE ControllerHandle,
62 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
63 )
64 {
65 VIRTIO_FS *VirtioFs;
66 EFI_STATUS Status;
67 EFI_STATUS CloseStatus;
68
69 VirtioFs = AllocatePool (sizeof *VirtioFs);
70 if (VirtioFs == NULL) {
71 return EFI_OUT_OF_RESOURCES;
72 }
73 VirtioFs->Signature = VIRTIO_FS_SIG;
74
75 Status = gBS->OpenProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
76 (VOID **)&VirtioFs->Virtio, This->DriverBindingHandle,
77 ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
78 if (EFI_ERROR (Status)) {
79 goto FreeVirtioFs;
80 }
81
82 Status = VirtioFsInit (VirtioFs);
83 if (EFI_ERROR (Status)) {
84 goto CloseVirtio;
85 }
86
87 Status = VirtioFsFuseInitSession (VirtioFs);
88 if (EFI_ERROR (Status)) {
89 goto UninitVirtioFs;
90 }
91
92 Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
93 VirtioFsExitBoot, VirtioFs, &VirtioFs->ExitBoot);
94 if (EFI_ERROR (Status)) {
95 goto UninitVirtioFs;
96 }
97
98 InitializeListHead (&VirtioFs->OpenFiles);
99 VirtioFs->SimpleFs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
100 VirtioFs->SimpleFs.OpenVolume = VirtioFsOpenVolume;
101
102 Status = gBS->InstallProtocolInterface (&ControllerHandle,
103 &gEfiSimpleFileSystemProtocolGuid, EFI_NATIVE_INTERFACE,
104 &VirtioFs->SimpleFs);
105 if (EFI_ERROR (Status)) {
106 goto CloseExitBoot;
107 }
108
109 return EFI_SUCCESS;
110
111 CloseExitBoot:
112 CloseStatus = gBS->CloseEvent (VirtioFs->ExitBoot);
113 ASSERT_EFI_ERROR (CloseStatus);
114
115 UninitVirtioFs:
116 VirtioFsUninit (VirtioFs);
117
118 CloseVirtio:
119 CloseStatus = gBS->CloseProtocol (ControllerHandle,
120 &gVirtioDeviceProtocolGuid, This->DriverBindingHandle,
121 ControllerHandle);
122 ASSERT_EFI_ERROR (CloseStatus);
123
124 FreeVirtioFs:
125 FreePool (VirtioFs);
126
127 return Status;
128 }
129
130 EFI_STATUS
131 EFIAPI
132 VirtioFsBindingStop (
133 IN EFI_DRIVER_BINDING_PROTOCOL *This,
134 IN EFI_HANDLE ControllerHandle,
135 IN UINTN NumberOfChildren,
136 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
137 )
138 {
139 EFI_STATUS Status;
140 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
141 VIRTIO_FS *VirtioFs;
142
143 Status = gBS->OpenProtocol (ControllerHandle,
144 &gEfiSimpleFileSystemProtocolGuid, (VOID **)&SimpleFs,
145 This->DriverBindingHandle, ControllerHandle,
146 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 VirtioFs = VIRTIO_FS_FROM_SIMPLE_FS (SimpleFs);
152
153 if (!IsListEmpty (&VirtioFs->OpenFiles)) {
154 return EFI_ACCESS_DENIED;
155 }
156
157 Status = gBS->UninstallProtocolInterface (ControllerHandle,
158 &gEfiSimpleFileSystemProtocolGuid, SimpleFs);
159 if (EFI_ERROR (Status)) {
160 return Status;
161 }
162
163 Status = gBS->CloseEvent (VirtioFs->ExitBoot);
164 ASSERT_EFI_ERROR (Status);
165
166 VirtioFsUninit (VirtioFs);
167
168 Status = gBS->CloseProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
169 This->DriverBindingHandle, ControllerHandle);
170 ASSERT_EFI_ERROR (Status);
171
172 FreePool (VirtioFs);
173
174 return EFI_SUCCESS;
175 }
176
177 EFI_STATUS
178 EFIAPI
179 VirtioFsGetDriverName (
180 IN EFI_COMPONENT_NAME2_PROTOCOL *This,
181 IN CHAR8 *Language,
182 OUT CHAR16 **DriverName
183 )
184 {
185 if (AsciiStrCmp (Language, "en") != 0) {
186 return EFI_UNSUPPORTED;
187 }
188 *DriverName = L"Virtio Filesystem Driver";
189 return EFI_SUCCESS;
190 }
191
192 EFI_STATUS
193 EFIAPI
194 VirtioFsGetControllerName (
195 IN EFI_COMPONENT_NAME2_PROTOCOL *This,
196 IN EFI_HANDLE ControllerHandle,
197 IN EFI_HANDLE ChildHandle OPTIONAL,
198 IN CHAR8 *Language,
199 OUT CHAR16 **ControllerName
200 )
201 {
202 return EFI_UNSUPPORTED;
203 }
204
205 //
206 // Entry point of this driver.
207 //
208 EFI_STATUS
209 EFIAPI
210 VirtioFsEntryPoint (
211 IN EFI_HANDLE ImageHandle,
212 IN EFI_SYSTEM_TABLE *SystemTable
213 )
214 {
215 EFI_STATUS Status;
216
217 mDriverBinding.Supported = VirtioFsBindingSupported;
218 mDriverBinding.Start = VirtioFsBindingStart;
219 mDriverBinding.Stop = VirtioFsBindingStop;
220 mDriverBinding.Version = 0x10;
221 mDriverBinding.ImageHandle = ImageHandle;
222 mDriverBinding.DriverBindingHandle = ImageHandle;
223
224 mComponentName2.GetDriverName = VirtioFsGetDriverName;
225 mComponentName2.GetControllerName = VirtioFsGetControllerName;
226 mComponentName2.SupportedLanguages = "en";
227
228 Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
229 &gEfiDriverBindingProtocolGuid, &mDriverBinding,
230 &gEfiComponentName2ProtocolGuid, &mComponentName2, NULL);
231 return Status;
232 }