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