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