]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c
EmulatorPkg: Add -D DISABLE_NEW_DEPRECATED_INTERFACES
[mirror_edk2.git] / EmulatorPkg / EmuBusDriverDxe / EmuBusDriverDxe.c
CommitLineData
949f388f 1/** @file\r
2 Emu Bus driver\r
224e1333 3\r
9e3ab94d 4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
949f388f 5Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
e3ba31da 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
949f388f 7\r
8\r
9**/\r
10\r
11#include "EmuBusDriverDxe.h"\r
12\r
13\r
14\r
15//\r
16// DriverBinding protocol global\r
17//\r
18EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding = {\r
19 EmuBusDriverBindingSupported,\r
20 EmuBusDriverBindingStart,\r
21 EmuBusDriverBindingStop,\r
22 0xa,\r
23 NULL,\r
24 NULL\r
25};\r
26\r
27\r
28\r
29EFI_STATUS\r
30EFIAPI\r
31EmuBusDriverBindingSupported (\r
32 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
33 IN EFI_HANDLE ControllerHandle,\r
34 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
35 )\r
36{\r
37 EFI_STATUS Status;\r
38 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
39 EMU_THUNK_PROTOCOL *EmuThunk;\r
949f388f 40\r
41 //\r
42 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure\r
43 // it is a legal Device Path Node for this bus driver's children.\r
44 //\r
45 if (RemainingDevicePath != NULL) {\r
46 //\r
d18d8a1d 47 // Check if RemainingDevicePath is the End of Device Path Node,\r
949f388f 48 // if yes, go on checking other conditions\r
49 //\r
50 if (!IsDevicePathEnd (RemainingDevicePath)) {\r
51 //\r
52 // If RemainingDevicePath isn't the End of Device Path Node,\r
53 // check its validation\r
54 //\r
55 if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||\r
56 RemainingDevicePath->SubType != HW_VENDOR_DP ||\r
57 DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {\r
58 return EFI_UNSUPPORTED;\r
59 }\r
60 }\r
61 }\r
d18d8a1d 62\r
949f388f 63 //\r
64 // Open the IO Abstraction(s) needed to perform the supported test\r
65 //\r
66 Status = gBS->OpenProtocol (\r
67 ControllerHandle,\r
68 &gEmuThunkProtocolGuid,\r
69 (VOID **)&EmuThunk ,\r
70 This->DriverBindingHandle,\r
71 ControllerHandle,\r
72 EFI_OPEN_PROTOCOL_BY_DRIVER\r
73 );\r
74 if (Status == EFI_ALREADY_STARTED) {\r
75 return EFI_SUCCESS;\r
76 }\r
77\r
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
82 //\r
83 // Close the I/O Abstraction(s) used to perform the supported test\r
84 //\r
85 gBS->CloseProtocol (\r
86 ControllerHandle,\r
87 &gEmuThunkProtocolGuid,\r
88 This->DriverBindingHandle,\r
89 ControllerHandle\r
90 );\r
91\r
92 //\r
93 // Open the EFI Device Path protocol needed to perform the supported test\r
94 //\r
95 Status = gBS->OpenProtocol (\r
96 ControllerHandle,\r
97 &gEfiDevicePathProtocolGuid,\r
98 (VOID **)&ParentDevicePath,\r
99 This->DriverBindingHandle,\r
100 ControllerHandle,\r
101 EFI_OPEN_PROTOCOL_BY_DRIVER\r
102 );\r
103 if (Status == EFI_ALREADY_STARTED) {\r
104 return EFI_SUCCESS;\r
105 }\r
106\r
107 if (EFI_ERROR (Status)) {\r
108 return Status;\r
109 }\r
110\r
111\r
112 //\r
113 // Close protocol, don't use device path protocol in the Support() function\r
114 //\r
115 gBS->CloseProtocol (\r
116 ControllerHandle,\r
117 &gEfiDevicePathProtocolGuid,\r
118 This->DriverBindingHandle,\r
119 ControllerHandle\r
120 );\r
121\r
122 return Status;\r
123}\r
124\r
125\r
126EFI_STATUS\r
127EFIAPI\r
128EmuBusDriverBindingStart (\r
129 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
130 IN EFI_HANDLE ControllerHandle,\r
131 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
132 )\r
133{\r
134 EFI_STATUS Status;\r
135 EFI_STATUS InstallStatus;\r
136 EMU_THUNK_PROTOCOL *EmuThunk;\r
137 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
138 EMU_IO_DEVICE *EmuDevice;\r
139 EMU_BUS_DEVICE *EmuBusDevice;\r
140 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
949f388f 141 UINT16 ComponentName[512];\r
142 EMU_VENDOR_DEVICE_PATH_NODE *Node;\r
143 BOOLEAN CreateDevice;\r
949f388f 144\r
54e0b04c 145 InstallStatus = EFI_UNSUPPORTED;\r
949f388f 146 Status = EFI_UNSUPPORTED;\r
147\r
148 //\r
149 // Grab the protocols we need\r
150 //\r
151 Status = gBS->OpenProtocol (\r
152 ControllerHandle,\r
153 &gEfiDevicePathProtocolGuid,\r
154 (VOID **)&ParentDevicePath,\r
155 This->DriverBindingHandle,\r
156 ControllerHandle,\r
157 EFI_OPEN_PROTOCOL_BY_DRIVER\r
158 );\r
159 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
160 return Status;\r
161 }\r
162\r
163 Status = gBS->OpenProtocol (\r
164 ControllerHandle,\r
165 &gEmuThunkProtocolGuid,\r
166 (VOID **)&EmuThunk,\r
167 This->DriverBindingHandle,\r
168 ControllerHandle,\r
169 EFI_OPEN_PROTOCOL_BY_DRIVER\r
170 );\r
171 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
172 return Status;\r
173 }\r
174\r
175 if (Status != EFI_ALREADY_STARTED) {\r
176 EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));\r
177 if (EmuBusDevice == NULL) {\r
178 return EFI_OUT_OF_RESOURCES;\r
179 }\r
180\r
181 EmuBusDevice->Signature = EMU_BUS_DEVICE_SIGNATURE;\r
182 EmuBusDevice->ControllerNameTable = NULL;\r
183\r
184 AddUnicodeString2 (\r
185 "eng",\r
186 gEmuBusDriverComponentName.SupportedLanguages,\r
187 &EmuBusDevice->ControllerNameTable,\r
bb89ec1a 188 L"Emulator Bus Controller",\r
949f388f 189 TRUE\r
190 );\r
191 AddUnicodeString2 (\r
192 "en",\r
193 gEmuBusDriverComponentName2.SupportedLanguages,\r
194 &EmuBusDevice->ControllerNameTable,\r
bb89ec1a 195 L"Emulator Bus Controller",\r
949f388f 196 FALSE\r
197 );\r
198\r
199\r
200 Status = gBS->InstallMultipleProtocolInterfaces (\r
201 &ControllerHandle,\r
202 &gEfiCallerIdGuid, EmuBusDevice,\r
203 NULL\r
204 );\r
205 if (EFI_ERROR (Status)) {\r
206 FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);\r
207 gBS->FreePool (EmuBusDevice);\r
208 return Status;\r
209 }\r
210 }\r
211\r
212\r
213 for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {\r
214 Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);\r
215 if (EFI_ERROR (Status)) {\r
216 break;\r
217 }\r
218\r
219 CreateDevice = TRUE;\r
220 if (RemainingDevicePath != NULL) {\r
221 CreateDevice = FALSE;\r
222 //\r
d18d8a1d 223 // Check if RemainingDevicePath is the End of Device Path Node,\r
224 // if yes, don't create any child device\r
949f388f 225 //\r
226 if (!IsDevicePathEnd (RemainingDevicePath)) {\r
227 //\r
228 // If RemainingDevicePath isn't the End of Device Path Node,\r
229 // check its validation\r
230 //\r
231 Node = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;\r
232 if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&\r
233 Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&\r
234 DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)\r
235 ) {\r
236 if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {\r
237 CreateDevice = TRUE;\r
238 }\r
239 }\r
240 }\r
241 }\r
242\r
243 if (CreateDevice) {\r
244 //\r
245 // Allocate instance structure, and fill in parent information.\r
246 //\r
247 EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));\r
248 if (EmuDevice == NULL) {\r
249 return EFI_OUT_OF_RESOURCES;\r
250 }\r
251\r
252 EmuDevice->Handle = NULL;\r
253 EmuDevice->ControllerHandle = ControllerHandle;\r
254 EmuDevice->ParentDevicePath = ParentDevicePath;\r
255 CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));\r
d18d8a1d 256\r
949f388f 257 EmuDevice->ControllerNameTable = NULL;\r
258\r
9e3ab94d
MK
259 StrnCpyS (\r
260 ComponentName,\r
261 sizeof (ComponentName) / sizeof (CHAR16),\r
262 EmuIoThunk->ConfigString,\r
263 sizeof (ComponentName) / sizeof (CHAR16)\r
264 );\r
949f388f 265\r
266 EmuDevice->DevicePath = EmuBusCreateDevicePath (\r
267 ParentDevicePath,\r
268 EmuIoThunk->Protocol,\r
269 EmuIoThunk->Instance\r
270 );\r
271 if (EmuDevice->DevicePath == NULL) {\r
272 gBS->FreePool (EmuDevice);\r
273 return EFI_OUT_OF_RESOURCES;\r
274 }\r
275\r
276 AddUnicodeString (\r
277 "eng",\r
278 gEmuBusDriverComponentName.SupportedLanguages,\r
279 &EmuDevice->ControllerNameTable,\r
280 ComponentName\r
281 );\r
282\r
283 EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;\r
284\r
285 InstallStatus = gBS->InstallMultipleProtocolInterfaces (\r
286 &EmuDevice->Handle,\r
287 &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,\r
288 &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk,\r
289 NULL\r
290 );\r
291 if (EFI_ERROR (InstallStatus)) {\r
292 FreeUnicodeStringTable (EmuDevice->ControllerNameTable);\r
293 gBS->FreePool (EmuDevice);\r
294 } else {\r
295 //\r
296 // Open For Child Device\r
297 //\r
298 Status = gBS->OpenProtocol (\r
299 ControllerHandle,\r
300 &gEmuThunkProtocolGuid,\r
301 (VOID **)&EmuThunk ,\r
302 This->DriverBindingHandle,\r
303 EmuDevice->Handle,\r
304 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
305 );\r
306 if (!EFI_ERROR (Status)) {\r
307 InstallStatus = EFI_SUCCESS;\r
308 }\r
309 }\r
310 }\r
311 }\r
312\r
313 return InstallStatus;\r
314}\r
315\r
316\r
317EFI_STATUS\r
318EFIAPI\r
319EmuBusDriverBindingStop (\r
320 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
321 IN EFI_HANDLE ControllerHandle,\r
322 IN UINTN NumberOfChildren,\r
323 IN EFI_HANDLE *ChildHandleBuffer\r
324 )\r
325{\r
326 EFI_STATUS Status;\r
327 UINTN Index;\r
328 BOOLEAN AllChildrenStopped;\r
329 EMU_IO_THUNK_PROTOCOL *EmuIoThunk;\r
330 EMU_BUS_DEVICE *EmuBusDevice;\r
331 EMU_IO_DEVICE *EmuDevice;\r
332 EMU_THUNK_PROTOCOL *EmuThunk;\r
333\r
334 //\r
335 // Complete all outstanding transactions to Controller.\r
336 // Don't allow any new transaction to Controller to be started.\r
337 //\r
338\r
339 if (NumberOfChildren == 0) {\r
340 //\r
341 // Close the bus driver\r
342 //\r
343 Status = gBS->OpenProtocol (\r
344 ControllerHandle,\r
345 &gEfiCallerIdGuid,\r
346 (VOID **)&EmuBusDevice,\r
347 This->DriverBindingHandle,\r
348 ControllerHandle,\r
349 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
350 );\r
351 if (EFI_ERROR (Status)) {\r
352 return Status;\r
353 }\r
354\r
355 gBS->UninstallMultipleProtocolInterfaces (\r
356 ControllerHandle,\r
357 &gEfiCallerIdGuid, EmuBusDevice,\r
358 NULL\r
359 );\r
360\r
361 FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);\r
362\r
363 gBS->FreePool (EmuBusDevice);\r
364\r
365 gBS->CloseProtocol (\r
366 ControllerHandle,\r
367 &gEmuThunkProtocolGuid,\r
368 This->DriverBindingHandle,\r
369 ControllerHandle\r
370 );\r
371\r
372 gBS->CloseProtocol (\r
373 ControllerHandle,\r
374 &gEfiDevicePathProtocolGuid,\r
375 This->DriverBindingHandle,\r
376 ControllerHandle\r
377 );\r
378 return EFI_SUCCESS;\r
379 }\r
380\r
381 AllChildrenStopped = TRUE;\r
382\r
383 for (Index = 0; Index < NumberOfChildren; Index++) {\r
384\r
385 Status = gBS->OpenProtocol (\r
386 ChildHandleBuffer[Index],\r
387 &gEmuIoThunkProtocolGuid,\r
388 (VOID **)&EmuIoThunk,\r
389 This->DriverBindingHandle,\r
390 ControllerHandle,\r
391 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
392 );\r
393 if (!EFI_ERROR (Status)) {\r
394 EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);\r
395\r
396 Status = gBS->CloseProtocol (\r
397 ControllerHandle,\r
398 &gEmuThunkProtocolGuid,\r
399 This->DriverBindingHandle,\r
400 EmuDevice->Handle\r
401 );\r
402\r
403 Status = gBS->UninstallMultipleProtocolInterfaces (\r
404 EmuDevice->Handle,\r
405 &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,\r
f2a74dae 406 &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk,\r
949f388f 407 NULL\r
408 );\r
409\r
410 if (EFI_ERROR (Status)) {\r
411 gBS->OpenProtocol (\r
412 ControllerHandle,\r
413 &gEmuThunkProtocolGuid,\r
414 (VOID **) &EmuThunk ,\r
415 This->DriverBindingHandle,\r
416 EmuDevice->Handle,\r
417 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
418 );\r
419 } else {\r
420 //\r
421 // Close the child handle\r
422 //\r
423 FreeUnicodeStringTable (EmuDevice->ControllerNameTable);\r
424 FreePool (EmuDevice);\r
425 }\r
426 }\r
427\r
428 if (EFI_ERROR (Status)) {\r
429 AllChildrenStopped = FALSE;\r
430 }\r
431 }\r
432\r
433 if (!AllChildrenStopped) {\r
434 return EFI_DEVICE_ERROR;\r
435 }\r
436\r
437 return EFI_SUCCESS;\r
438}\r
439\r
440\r
441/*++\r
442\r
443Routine Description:\r
444 Create a device path node using Guid and InstanceNumber and append it to\r
445 the passed in RootDevicePath\r
446\r
447Arguments:\r
448 RootDevicePath - Root of the device path to return.\r
449\r
450 Guid - GUID to use in vendor device path node.\r
451\r
452 InstanceNumber - Instance number to use in the vendor device path. This\r
453 argument is needed to make sure each device path is unique.\r
454\r
455Returns:\r
456\r
d18d8a1d 457 EFI_DEVICE_PATH_PROTOCOL\r
949f388f 458\r
459**/\r
460EFI_DEVICE_PATH_PROTOCOL *\r
461EmuBusCreateDevicePath (\r
462 IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,\r
463 IN EFI_GUID *Guid,\r
464 IN UINT16 InstanceNumber\r
465 )\r
466{\r
467 EMU_VENDOR_DEVICE_PATH_NODE DevicePath;\r
468\r
469 DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;\r
470 DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;\r
471 SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));\r
472\r
473 //\r
474 // The GUID defines the Class\r
475 //\r
476 CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));\r
477\r
478 //\r
479 // Add an instance number so we can make sure there are no Device Path\r
480 // duplication.\r
481 //\r
482 DevicePath.Instance = InstanceNumber;\r
483\r
484 return AppendDevicePathNode (\r
485 RootDevicePath,\r
486 (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath\r
487 );\r
488}\r
489\r
490\r
491\r
492/**\r
493 The user Entry Point for module EmuBusDriver. The user code starts with this function.\r
494\r
d18d8a1d 495 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
949f388f 496 @param[in] SystemTable A pointer to the EFI System Table.\r
d18d8a1d 497\r
949f388f 498 @retval EFI_SUCCESS The entry point is executed successfully.\r
499 @retval other Some error occurs when executing this entry point.\r
500\r
501**/\r
502EFI_STATUS\r
503EFIAPI\r
504InitializeEmuBusDriver (\r
505 IN EFI_HANDLE ImageHandle,\r
506 IN EFI_SYSTEM_TABLE *SystemTable\r
507 )\r
508{\r
509 EFI_STATUS Status;\r
510\r
511 Status = EfiLibInstallAllDriverProtocols (\r
512 ImageHandle,\r
513 SystemTable,\r
514 &gEmuBusDriverBinding,\r
515 ImageHandle,\r
516 &gEmuBusDriverComponentName,\r
517 NULL,\r
518 NULL\r
519 );\r
520 ASSERT_EFI_ERROR (Status);\r
521\r
522\r
523 return Status;\r
524}\r
525\r
526\r
527\r
528\r