]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioFsDxe/DriverBinding.c
OvmfPkg/VirtioFsDxe: Check GetDriverName arguments
[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 ((Language == NULL) || (DriverName == NULL)) {
222 return EFI_INVALID_PARAMETER;
223 }
224
225 if (AsciiStrCmp (Language, "en") != 0) {
226 return EFI_UNSUPPORTED;
227 }
228
229 *DriverName = L"Virtio Filesystem Driver";
230 return EFI_SUCCESS;
231 }
232
233 EFI_STATUS
234 EFIAPI
235 VirtioFsGetControllerName (
236 IN EFI_COMPONENT_NAME2_PROTOCOL *This,
237 IN EFI_HANDLE ControllerHandle,
238 IN EFI_HANDLE ChildHandle OPTIONAL,
239 IN CHAR8 *Language,
240 OUT CHAR16 **ControllerName
241 )
242 {
243 return EFI_UNSUPPORTED;
244 }
245
246 //
247 // Entry point of this driver.
248 //
249 EFI_STATUS
250 EFIAPI
251 VirtioFsEntryPoint (
252 IN EFI_HANDLE ImageHandle,
253 IN EFI_SYSTEM_TABLE *SystemTable
254 )
255 {
256 EFI_STATUS Status;
257
258 mDriverBinding.Supported = VirtioFsBindingSupported;
259 mDriverBinding.Start = VirtioFsBindingStart;
260 mDriverBinding.Stop = VirtioFsBindingStop;
261 mDriverBinding.Version = 0x10;
262 mDriverBinding.ImageHandle = ImageHandle;
263 mDriverBinding.DriverBindingHandle = ImageHandle;
264
265 mComponentName2.GetDriverName = VirtioFsGetDriverName;
266 mComponentName2.GetControllerName = VirtioFsGetControllerName;
267 mComponentName2.SupportedLanguages = "en";
268
269 Status = gBS->InstallMultipleProtocolInterfaces (
270 &ImageHandle,
271 &gEfiDriverBindingProtocolGuid,
272 &mDriverBinding,
273 &gEfiComponentName2ProtocolGuid,
274 &mComponentName2,
275 NULL
276 );
277 return Status;
278 }