]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioFsDxe/DriverBinding.c
OvmfPkg: Apply uncrustify changes
[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 (
39 ControllerHandle,
40 &gVirtioDeviceProtocolGuid,
41 (VOID **)&Virtio,
42 This->DriverBindingHandle,
43 ControllerHandle,
44 EFI_OPEN_PROTOCOL_BY_DRIVER
45 );
46 if (EFI_ERROR (Status)) {
47 return Status;
48 }
49
50 if (Virtio->SubSystemDeviceId != VIRTIO_SUBSYSTEM_FILESYSTEM) {
51 Status = EFI_UNSUPPORTED;
52 }
53
54 CloseStatus = gBS->CloseProtocol (
55 ControllerHandle,
56 &gVirtioDeviceProtocolGuid,
57 This->DriverBindingHandle,
58 ControllerHandle
59 );
60 ASSERT_EFI_ERROR (CloseStatus);
61
62 return Status;
63 }
64
65 EFI_STATUS
66 EFIAPI
67 VirtioFsBindingStart (
68 IN EFI_DRIVER_BINDING_PROTOCOL *This,
69 IN EFI_HANDLE ControllerHandle,
70 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
71 )
72 {
73 VIRTIO_FS *VirtioFs;
74 EFI_STATUS Status;
75 EFI_STATUS CloseStatus;
76
77 VirtioFs = AllocatePool (sizeof *VirtioFs);
78 if (VirtioFs == NULL) {
79 return EFI_OUT_OF_RESOURCES;
80 }
81
82 VirtioFs->Signature = VIRTIO_FS_SIG;
83
84 Status = gBS->OpenProtocol (
85 ControllerHandle,
86 &gVirtioDeviceProtocolGuid,
87 (VOID **)&VirtioFs->Virtio,
88 This->DriverBindingHandle,
89 ControllerHandle,
90 EFI_OPEN_PROTOCOL_BY_DRIVER
91 );
92 if (EFI_ERROR (Status)) {
93 goto FreeVirtioFs;
94 }
95
96 Status = VirtioFsInit (VirtioFs);
97 if (EFI_ERROR (Status)) {
98 goto CloseVirtio;
99 }
100
101 Status = VirtioFsFuseInitSession (VirtioFs);
102 if (EFI_ERROR (Status)) {
103 goto UninitVirtioFs;
104 }
105
106 Status = gBS->CreateEvent (
107 EVT_SIGNAL_EXIT_BOOT_SERVICES,
108 TPL_CALLBACK,
109 VirtioFsExitBoot,
110 VirtioFs,
111 &VirtioFs->ExitBoot
112 );
113 if (EFI_ERROR (Status)) {
114 goto UninitVirtioFs;
115 }
116
117 InitializeListHead (&VirtioFs->OpenFiles);
118 VirtioFs->SimpleFs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
119 VirtioFs->SimpleFs.OpenVolume = VirtioFsOpenVolume;
120
121 Status = gBS->InstallProtocolInterface (
122 &ControllerHandle,
123 &gEfiSimpleFileSystemProtocolGuid,
124 EFI_NATIVE_INTERFACE,
125 &VirtioFs->SimpleFs
126 );
127 if (EFI_ERROR (Status)) {
128 goto CloseExitBoot;
129 }
130
131 return EFI_SUCCESS;
132
133 CloseExitBoot:
134 CloseStatus = gBS->CloseEvent (VirtioFs->ExitBoot);
135 ASSERT_EFI_ERROR (CloseStatus);
136
137 UninitVirtioFs:
138 VirtioFsUninit (VirtioFs);
139
140 CloseVirtio:
141 CloseStatus = gBS->CloseProtocol (
142 ControllerHandle,
143 &gVirtioDeviceProtocolGuid,
144 This->DriverBindingHandle,
145 ControllerHandle
146 );
147 ASSERT_EFI_ERROR (CloseStatus);
148
149 FreeVirtioFs:
150 FreePool (VirtioFs);
151
152 return Status;
153 }
154
155 EFI_STATUS
156 EFIAPI
157 VirtioFsBindingStop (
158 IN EFI_DRIVER_BINDING_PROTOCOL *This,
159 IN EFI_HANDLE ControllerHandle,
160 IN UINTN NumberOfChildren,
161 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
162 )
163 {
164 EFI_STATUS Status;
165 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
166 VIRTIO_FS *VirtioFs;
167
168 Status = gBS->OpenProtocol (
169 ControllerHandle,
170 &gEfiSimpleFileSystemProtocolGuid,
171 (VOID **)&SimpleFs,
172 This->DriverBindingHandle,
173 ControllerHandle,
174 EFI_OPEN_PROTOCOL_GET_PROTOCOL
175 );
176 if (EFI_ERROR (Status)) {
177 return Status;
178 }
179
180 VirtioFs = VIRTIO_FS_FROM_SIMPLE_FS (SimpleFs);
181
182 if (!IsListEmpty (&VirtioFs->OpenFiles)) {
183 return EFI_ACCESS_DENIED;
184 }
185
186 Status = gBS->UninstallProtocolInterface (
187 ControllerHandle,
188 &gEfiSimpleFileSystemProtocolGuid,
189 SimpleFs
190 );
191 if (EFI_ERROR (Status)) {
192 return Status;
193 }
194
195 Status = gBS->CloseEvent (VirtioFs->ExitBoot);
196 ASSERT_EFI_ERROR (Status);
197
198 VirtioFsUninit (VirtioFs);
199
200 Status = gBS->CloseProtocol (
201 ControllerHandle,
202 &gVirtioDeviceProtocolGuid,
203 This->DriverBindingHandle,
204 ControllerHandle
205 );
206 ASSERT_EFI_ERROR (Status);
207
208 FreePool (VirtioFs);
209
210 return EFI_SUCCESS;
211 }
212
213 EFI_STATUS
214 EFIAPI
215 VirtioFsGetDriverName (
216 IN EFI_COMPONENT_NAME2_PROTOCOL *This,
217 IN CHAR8 *Language,
218 OUT CHAR16 **DriverName
219 )
220 {
221 if (AsciiStrCmp (Language, "en") != 0) {
222 return EFI_UNSUPPORTED;
223 }
224
225 *DriverName = L"Virtio Filesystem Driver";
226 return EFI_SUCCESS;
227 }
228
229 EFI_STATUS
230 EFIAPI
231 VirtioFsGetControllerName (
232 IN EFI_COMPONENT_NAME2_PROTOCOL *This,
233 IN EFI_HANDLE ControllerHandle,
234 IN EFI_HANDLE ChildHandle OPTIONAL,
235 IN CHAR8 *Language,
236 OUT CHAR16 **ControllerName
237 )
238 {
239 return EFI_UNSUPPORTED;
240 }
241
242 //
243 // Entry point of this driver.
244 //
245 EFI_STATUS
246 EFIAPI
247 VirtioFsEntryPoint (
248 IN EFI_HANDLE ImageHandle,
249 IN EFI_SYSTEM_TABLE *SystemTable
250 )
251 {
252 EFI_STATUS Status;
253
254 mDriverBinding.Supported = VirtioFsBindingSupported;
255 mDriverBinding.Start = VirtioFsBindingStart;
256 mDriverBinding.Stop = VirtioFsBindingStop;
257 mDriverBinding.Version = 0x10;
258 mDriverBinding.ImageHandle = ImageHandle;
259 mDriverBinding.DriverBindingHandle = ImageHandle;
260
261 mComponentName2.GetDriverName = VirtioFsGetDriverName;
262 mComponentName2.GetControllerName = VirtioFsGetControllerName;
263 mComponentName2.SupportedLanguages = "en";
264
265 Status = gBS->InstallMultipleProtocolInterfaces (
266 &ImageHandle,
267 &gEfiDriverBindingProtocolGuid,
268 &mDriverBinding,
269 &gEfiComponentName2ProtocolGuid,
270 &mComponentName2,
271 NULL
272 );
273 return Status;
274 }