]> git.proxmox.com Git - mirror_edk2.git/blame - EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.c
1. Removed #ifdef EDK_RELEASE_VERSION from all c files for all modules
[mirror_edk2.git] / EdkNt32Pkg / Dxe / WinNtThunk / Bus / WinNtBusDriver / WinNtBusDriver.c
CommitLineData
878ddf1f 1/*+++\r
2\r
ce8bd86e 3Copyright (c) 2006 - 2007, Intel Corporation\r
7f0ceb22 4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
878ddf1f 11\r
12Module Name:\r
13\r
14 WinNtBusDriver.c\r
15\r
16Abstract:\r
17\r
7f0ceb22 18This following section documents the envirnoment variables for the Win NT\r
19build. These variables are used to define the (virtual) hardware\r
878ddf1f 20configuration of the NT environment\r
21\r
7f0ceb22 22A ! can be used to seperate multiple instances in a variable. Each\r
23instance represents a seperate hardware device.\r
878ddf1f 24\r
25EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system\r
26EFI_WIN_NT_VIRTUAL_DISKS - maps to a device emulated by a file\r
27EFI_WIN_NT_FILE_SYSTEM - mouts a directory as a file system\r
28EFI_WIN_NT_CONSOLE - make a logical comand line window (only one!)\r
29EFI_WIN_NT_UGA - Builds UGA Windows of Width and Height\r
30EFI_WIN_NT_SERIAL_PORT - maps physical serial ports\r
31\r
32 <F>ixed - Fixed disk like a hard drive.\r
33 <R>emovable - Removable media like a floppy or CD-ROM.\r
34 Read <O>nly - Write protected device.\r
35 Read <W>rite - Read write device.\r
36 <block count> - Decimal number of blocks a device supports.\r
37 <block size> - Decimal number of bytes per block.\r
38\r
7f0ceb22 39 NT envirnonment variable contents. '<' and '>' are not part of the variable,\r
40 they are just used to make this help more readable. There should be no\r
41 spaces between the ';'. Extra spaces will break the variable. A '!' is\r
878ddf1f 42 used to seperate multiple devices in a variable.\r
43\r
7f0ceb22 44 EFI_WIN_NT_VIRTUAL_DISKS =\r
878ddf1f 45 <F | R><O | W>;<block count>;<block size>[!...]\r
46\r
47 EFI_WIN_NT_PHYSICAL_DISKS =\r
48 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]\r
49\r
50 Virtual Disks: These devices use a file to emulate a hard disk or removable\r
7f0ceb22 51 media device.\r
52\r
878ddf1f 53 Thus a 20 MB emulated hard drive would look like:\r
54 EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512\r
55\r
56 A 1.44MB emulated floppy with a block size of 1024 would look like:\r
57 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024\r
58\r
59 Physical Disks: These devices use NT to open a real device in your system\r
60\r
61 Thus a 120 MB floppy would look like:\r
62 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512\r
63\r
64 Thus a standard CD-ROM floppy would look like:\r
65 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048\r
66\r
7f0ceb22 67 EFI_WIN_NT_FILE_SYSTEM =\r
878ddf1f 68 <directory path>[!...]\r
69\r
70 Mounting the two directories C:\FOO and C:\BAR would look like:\r
71 EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar\r
72\r
7f0ceb22 73 EFI_WIN_NT_CONSOLE =\r
878ddf1f 74 <window title>\r
75\r
76 Declaring a text console window with the title "My EFI Console" woild look like:\r
77 EFI_WIN_NT_CONSOLE=My EFI Console\r
78\r
7f0ceb22 79 EFI_WIN_NT_UGA =\r
878ddf1f 80 <width> <height>[!...]\r
81\r
82 Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:\r
83 Example : EFI_WIN_NT_UGA=800 600!1024 768\r
84\r
7f0ceb22 85 EFI_WIN_NT_SERIAL_PORT =\r
878ddf1f 86 <port name>[!...]\r
87\r
88 Declaring two serial ports on COM1 and COM2 would look like:\r
89 Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2\r
90\r
91 EFI_WIN_NT_PASS_THROUGH =\r
92 <BaseAddress>;<Bus#>;<Device#>;<Function#>\r
93\r
94 Declaring a base address of 0xE0000000 (used for PCI Express devices)\r
95 and having NT32 talk to a device located at bus 0, device 1, function 0:\r
96 Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0\r
97\r
98---*/\r
99\r
100#include "WinNtBusDriver.h"\r
878ddf1f 101\r
7f0ceb22 102extern EFI_GUID gWinNtBusDriverGuid;\r
878ddf1f 103//\r
104// DriverBinding protocol global\r
105//\r
106EFI_DRIVER_BINDING_PROTOCOL gWinNtBusDriverBinding = {\r
107 WinNtBusDriverBindingSupported,\r
108 WinNtBusDriverBindingStart,\r
109 WinNtBusDriverBindingStop,\r
8b018de6 110 0xa,\r
878ddf1f 111 NULL,\r
112 NULL\r
113};\r
114\r
115#define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))\r
116\r
117//\r
118// Table to map NT Environment variable to the GUID that should be in\r
119// device path.\r
120//\r
121static NT_PCD_ENTRY mPcdEnvironment[] = {\r
122 PcdToken(PcdWinNtConsole), &gEfiWinNtConsoleGuid,\r
123 PcdToken(PcdWinNtUga), &gEfiWinNtUgaGuid,\r
72b695f3 124 PcdToken(PcdWinNtGop), &gEfiWinNtGopGuid,\r
878ddf1f 125 PcdToken(PcdWinNtSerialPort), &gEfiWinNtSerialPortGuid,\r
126 PcdToken(PcdWinNtFileSystem), &gEfiWinNtFileSystemGuid,\r
127 PcdToken(PcdWinNtVirtualDisk), &gEfiWinNtVirtualDisksGuid,\r
128 PcdToken(PcdWinNtPhysicalDisk), &gEfiWinNtPhysicalDisksGuid,\r
129 PcdToken(PcdWinNtCpuModel), &gEfiWinNtCPUModelGuid,\r
130 PcdToken(PcdWinNtCpuSpeed), &gEfiWinNtCPUSpeedGuid,\r
131 PcdToken(PcdWinNtMemorySize), &gEfiWinNtMemoryGuid\r
132};\r
133\r
134VOID *\r
135AllocateMemory (\r
136 IN UINTN Size\r
137 )\r
138{\r
139 EFI_STATUS Status;\r
140 VOID *Buffer;\r
141\r
142 Status = gBS->AllocatePool (\r
143 EfiBootServicesData,\r
144 Size,\r
145 (VOID *)&Buffer\r
146 );\r
147 if (EFI_ERROR (Status)) {\r
148 ASSERT (FALSE);\r
149 return NULL;\r
150 }\r
151 return Buffer;\r
152}\r
153\r
154\r
155EFI_STATUS\r
156EFIAPI\r
157WinNtBusDriverBindingSupported (\r
158 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
159 IN EFI_HANDLE ControllerHandle,\r
160 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
161 )\r
162/*++\r
163\r
164Routine Description:\r
165\r
166Arguments:\r
167\r
168Returns:\r
169\r
170 None\r
171\r
172--*/\r
173// TODO: This - add argument and description to function comment\r
174// TODO: ControllerHandle - add argument and description to function comment\r
175// TODO: RemainingDevicePath - add argument and description to function comment\r
176// TODO: EFI_UNSUPPORTED - add return value to function comment\r
177// TODO: EFI_UNSUPPORTED - add return value to function comment\r
178// TODO: EFI_SUCCESS - add return value to function comment\r
179// TODO: EFI_SUCCESS - add return value to function comment\r
180{\r
181 EFI_STATUS Status;\r
182 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
183 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
184 UINTN Index;\r
185\r
186 //\r
187 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure\r
188 // it is a legal Device Path Node for this bus driver's children.\r
189 //\r
190 if (RemainingDevicePath != NULL) {\r
191 if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||\r
192 RemainingDevicePath->SubType != HW_VENDOR_DP ||\r
193 DevicePathNodeLength(RemainingDevicePath) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE)) {\r
194 return EFI_UNSUPPORTED;\r
195 }\r
196\r
197 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {\r
198 if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {\r
199 break;\r
200 }\r
201 }\r
202\r
203 if (Index >= NT_PCD_ARRAY_SIZE) {\r
204 return EFI_UNSUPPORTED;\r
205 }\r
206 }\r
7f0ceb22 207\r
878ddf1f 208 //\r
209 // Open the IO Abstraction(s) needed to perform the supported test\r
210 //\r
211 Status = gBS->OpenProtocol (\r
212 ControllerHandle,\r
213 &gEfiDevicePathProtocolGuid,\r
214 &ParentDevicePath,\r
215 This->DriverBindingHandle,\r
216 ControllerHandle,\r
217 EFI_OPEN_PROTOCOL_BY_DRIVER\r
218 );\r
219 if (Status == EFI_ALREADY_STARTED) {\r
220 return EFI_SUCCESS;\r
221 }\r
222\r
223 if (EFI_ERROR (Status)) {\r
224 return Status;\r
225 }\r
226\r
227 gBS->CloseProtocol (\r
228 ControllerHandle,\r
229 &gEfiDevicePathProtocolGuid,\r
230 This->DriverBindingHandle,\r
231 ControllerHandle\r
232 );\r
233\r
234 Status = gBS->OpenProtocol (\r
235 ControllerHandle,\r
236 &gEfiWinNtThunkProtocolGuid,\r
237 &WinNtThunk,\r
238 This->DriverBindingHandle,\r
239 ControllerHandle,\r
240 EFI_OPEN_PROTOCOL_BY_DRIVER\r
241 );\r
242 if (Status == EFI_ALREADY_STARTED) {\r
243 return EFI_SUCCESS;\r
244 }\r
245\r
246 if (EFI_ERROR (Status)) {\r
247 return Status;\r
248 }\r
249\r
250 //\r
251 // Since we call through WinNtThunk we need to make sure it's valid\r
252 //\r
253 Status = EFI_SUCCESS;\r
254 if (WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {\r
255 Status = EFI_UNSUPPORTED;\r
256 }\r
257\r
258 //\r
259 // Close the I/O Abstraction(s) used to perform the supported test\r
260 //\r
261 gBS->CloseProtocol (\r
262 ControllerHandle,\r
263 &gEfiWinNtThunkProtocolGuid,\r
264 This->DriverBindingHandle,\r
265 ControllerHandle\r
266 );\r
267\r
268 return Status;\r
269}\r
270\r
271EFI_STATUS\r
272EFIAPI\r
273WinNtBusDriverBindingStart (\r
274 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
275 IN EFI_HANDLE ControllerHandle,\r
276 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
277 )\r
278/*++\r
279\r
280Routine Description:\r
281\r
282Arguments:\r
283\r
284Returns:\r
285\r
286 None\r
287\r
288--*/\r
289// TODO: This - add argument and description to function comment\r
290// TODO: ControllerHandle - add argument and description to function comment\r
291// TODO: RemainingDevicePath - add argument and description to function comment\r
292// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
293// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
294// TODO: EFI_SUCCESS - add return value to function comment\r
295{\r
296 EFI_STATUS Status;\r
297 EFI_STATUS InstallStatus;\r
298 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
299 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
300 WIN_NT_BUS_DEVICE *WinNtBusDevice;\r
301 WIN_NT_IO_DEVICE *WinNtDevice;\r
302 UINTN Index;\r
303 CHAR16 *StartString;\r
304 CHAR16 *SubString;\r
305 UINT16 Count;\r
306 UINTN StringSize;\r
307 UINT16 ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];\r
308 WIN_NT_VENDOR_DEVICE_PATH_NODE *Node;\r
309 BOOLEAN CreateDevice;\r
310 CHAR16 *TempStr;\r
311 CHAR16 *PcdTempStr;\r
312 UINTN TempStrSize;\r
313\r
878ddf1f 314 Status = EFI_UNSUPPORTED;\r
315\r
316 //\r
317 // Grab the protocols we need\r
318 //\r
319 Status = gBS->OpenProtocol (\r
320 ControllerHandle,\r
321 &gEfiDevicePathProtocolGuid,\r
322 &ParentDevicePath,\r
323 This->DriverBindingHandle,\r
324 ControllerHandle,\r
325 EFI_OPEN_PROTOCOL_BY_DRIVER\r
326 );\r
327 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
328 return Status;\r
329 }\r
330\r
331 Status = gBS->OpenProtocol (\r
332 ControllerHandle,\r
333 &gEfiWinNtThunkProtocolGuid,\r
334 &WinNtThunk,\r
335 This->DriverBindingHandle,\r
336 ControllerHandle,\r
337 EFI_OPEN_PROTOCOL_BY_DRIVER\r
338 );\r
339 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
340 return Status;\r
341 }\r
342\r
343 if (Status != EFI_ALREADY_STARTED) {\r
344 Status = gBS->AllocatePool (\r
345 EfiBootServicesData,\r
346 sizeof (WIN_NT_BUS_DEVICE),\r
347 (VOID *) &WinNtBusDevice\r
348 );\r
349 if (EFI_ERROR (Status)) {\r
350 return Status;\r
351 }\r
352\r
353 WinNtBusDevice->Signature = WIN_NT_BUS_DEVICE_SIGNATURE;\r
354 WinNtBusDevice->ControllerNameTable = NULL;\r
355\r
356 AddUnicodeString (\r
357 "eng",\r
358 gWinNtBusDriverComponentName.SupportedLanguages,\r
359 &WinNtBusDevice->ControllerNameTable,\r
360 L"Windows Bus Controller"\r
361 );\r
362\r
363 Status = gBS->InstallMultipleProtocolInterfaces (\r
364 &ControllerHandle,\r
365 &gWinNtBusDriverGuid,\r
366 WinNtBusDevice,\r
367 NULL\r
368 );\r
369 if (EFI_ERROR (Status)) {\r
370 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);\r
371 gBS->FreePool (WinNtBusDevice);\r
372 return Status;\r
373 }\r
374 }\r
375\r
376 //\r
377 // Loop on the Variable list. Parse each variable to produce a set of handles that\r
378 // represent virtual hardware devices.\r
379 //\r
380 InstallStatus = EFI_NOT_FOUND;\r
381 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {\r
382 PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);\r
383 ASSERT (PcdTempStr != NULL);\r
384\r
385 TempStrSize = StrLen (PcdTempStr);\r
386 TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);\r
387 StrCpy (TempStr, PcdTempStr);\r
388\r
389 StartString = TempStr;\r
390\r
391 //\r
392 // Parse the envirnment variable into sub strings using '!' as a delimator.\r
393 // Each substring needs it's own handle to be added to the system. This code\r
394 // does not understand the sub string. Thats the device drivers job.\r
395 //\r
396 Count = 0;\r
397 while (*StartString != '\0') {\r
398\r
399 //\r
400 // Find the end of the sub string\r
401 //\r
402 SubString = StartString;\r
403 while (*SubString != '\0' && *SubString != '!') {\r
404 SubString++;\r
405 }\r
406\r
407 if (*SubString == '!') {\r
408 //\r
409 // Replace token with '\0' to make sub strings. If this is the end\r
410 // of the string SubString will already point to NULL.\r
411 //\r
412 *SubString = '\0';\r
413 SubString++;\r
414 }\r
415\r
416 CreateDevice = TRUE;\r
417 if (RemainingDevicePath != NULL) {\r
418 CreateDevice = FALSE;\r
419 Node = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;\r
420 if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&\r
421 Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&\r
422 DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)\r
423 ) {\r
424 if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&\r
425 Node->Instance == Count\r
426 ) {\r
427 CreateDevice = TRUE;\r
428 }\r
429 }\r
430 }\r
431\r
432 if (CreateDevice) {\r
433\r
434 //\r
435 // Allocate instance structure, and fill in parent information.\r
436 //\r
437 WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));\r
438 if (WinNtDevice == NULL) {\r
439 return EFI_OUT_OF_RESOURCES;\r
440 }\r
441\r
442 WinNtDevice->Handle = NULL;\r
443 WinNtDevice->ControllerHandle = ControllerHandle;\r
444 WinNtDevice->ParentDevicePath = ParentDevicePath;\r
445\r
446 WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;\r
447\r
448 //\r
449 // Plus 2 to account for the NULL at the end of the Unicode string\r
450 //\r
451 StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);\r
452 WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);\r
453 if (WinNtDevice->WinNtIo.EnvString != NULL) {\r
454 CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);\r
455 }\r
456\r
457 WinNtDevice->ControllerNameTable = NULL;\r
458\r
c4bbb32b 459 WinNtThunk->SPrintf (ComponentName, sizeof (ComponentName), L"%s", WinNtDevice->WinNtIo.EnvString);\r
878ddf1f 460\r
461 WinNtDevice->DevicePath = WinNtBusCreateDevicePath (\r
462 ParentDevicePath,\r
463 mPcdEnvironment[Index].DevicePathGuid,\r
464 Count\r
465 );\r
466 if (WinNtDevice->DevicePath == NULL) {\r
467 gBS->FreePool (WinNtDevice);\r
468 return EFI_OUT_OF_RESOURCES;\r
469 }\r
470\r
471 AddUnicodeString (\r
472 "eng",\r
473 gWinNtBusDriverComponentName.SupportedLanguages,\r
474 &WinNtDevice->ControllerNameTable,\r
475 ComponentName\r
476 );\r
477\r
478 WinNtDevice->WinNtIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;\r
479 WinNtDevice->WinNtIo.InstanceNumber = Count;\r
480\r
481 WinNtDevice->Signature = WIN_NT_IO_DEVICE_SIGNATURE;\r
482\r
483 Status = gBS->InstallMultipleProtocolInterfaces (\r
484 &WinNtDevice->Handle,\r
485 &gEfiDevicePathProtocolGuid,\r
486 WinNtDevice->DevicePath,\r
487 &gEfiWinNtIoProtocolGuid,\r
488 &WinNtDevice->WinNtIo,\r
489 NULL\r
490 );\r
491 if (EFI_ERROR (Status)) {\r
492 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);\r
493 gBS->FreePool (WinNtDevice);\r
494 } else {\r
495 //\r
496 // Open For Child Device\r
497 //\r
498 Status = gBS->OpenProtocol (\r
499 ControllerHandle,\r
500 &gEfiWinNtThunkProtocolGuid,\r
501 &WinNtThunk,\r
502 This->DriverBindingHandle,\r
503 WinNtDevice->Handle,\r
504 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
505 );\r
506 if (!EFI_ERROR (Status)) {\r
507 InstallStatus = EFI_SUCCESS;\r
508 }\r
509 }\r
510 }\r
511\r
512 //\r
513 // Parse Next sub string. This will point to '\0' if we are at the end.\r
514 //\r
515 Count++;\r
516 StartString = SubString;\r
517 }\r
518\r
519 gBS->FreePool (TempStr);\r
520 }\r
521\r
522 return EFI_SUCCESS;\r
523}\r
524\r
525\r
526EFI_STATUS\r
527EFIAPI\r
528WinNtBusDriverBindingStop (\r
529 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
530 IN EFI_HANDLE ControllerHandle,\r
531 IN UINTN NumberOfChildren,\r
532 IN EFI_HANDLE *ChildHandleBuffer\r
533 )\r
534/*++\r
535\r
536Routine Description:\r
537\r
538Arguments:\r
539\r
540Returns:\r
541\r
542 None\r
543\r
544--*/\r
545// TODO: This - add argument and description to function comment\r
546// TODO: ControllerHandle - add argument and description to function comment\r
547// TODO: NumberOfChildren - add argument and description to function comment\r
548// TODO: ChildHandleBuffer - add argument and description to function comment\r
549// TODO: EFI_SUCCESS - add return value to function comment\r
550// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
551// TODO: EFI_SUCCESS - add return value to function comment\r
552{\r
553 EFI_STATUS Status;\r
554 UINTN Index;\r
555 BOOLEAN AllChildrenStopped;\r
556 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;\r
557 WIN_NT_BUS_DEVICE *WinNtBusDevice;\r
558 WIN_NT_IO_DEVICE *WinNtDevice;\r
559 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
560\r
561 //\r
562 // Complete all outstanding transactions to Controller.\r
563 // Don't allow any new transaction to Controller to be started.\r
564 //\r
565\r
566 if (NumberOfChildren == 0) {\r
567 //\r
568 // Close the bus driver\r
569 //\r
570 Status = gBS->OpenProtocol (\r
571 ControllerHandle,\r
572 &gWinNtBusDriverGuid,\r
573 &WinNtBusDevice,\r
574 This->DriverBindingHandle,\r
575 ControllerHandle,\r
576 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
577 );\r
578 if (EFI_ERROR (Status)) {\r
579 return Status;\r
580 }\r
581\r
582 gBS->UninstallMultipleProtocolInterfaces (\r
583 ControllerHandle,\r
584 &gWinNtBusDriverGuid,\r
585 WinNtBusDevice,\r
586 NULL\r
587 );\r
588\r
589 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);\r
590\r
591 gBS->FreePool (WinNtBusDevice);\r
592\r
593 gBS->CloseProtocol (\r
594 ControllerHandle,\r
595 &gEfiWinNtThunkProtocolGuid,\r
596 This->DriverBindingHandle,\r
597 ControllerHandle\r
598 );\r
599\r
600 gBS->CloseProtocol (\r
601 ControllerHandle,\r
602 &gEfiDevicePathProtocolGuid,\r
603 This->DriverBindingHandle,\r
604 ControllerHandle\r
605 );\r
606 return EFI_SUCCESS;\r
607 }\r
608\r
609 AllChildrenStopped = TRUE;\r
610\r
611 for (Index = 0; Index < NumberOfChildren; Index++) {\r
612\r
613 Status = gBS->OpenProtocol (\r
614 ChildHandleBuffer[Index],\r
615 &gEfiWinNtIoProtocolGuid,\r
616 &WinNtIo,\r
617 This->DriverBindingHandle,\r
618 ControllerHandle,\r
619 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
620 );\r
621 if (!EFI_ERROR (Status)) {\r
622\r
623 WinNtDevice = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);\r
624\r
625 Status = gBS->CloseProtocol (\r
626 ControllerHandle,\r
627 &gEfiWinNtThunkProtocolGuid,\r
628 This->DriverBindingHandle,\r
629 WinNtDevice->Handle\r
630 );\r
631\r
632 Status = gBS->UninstallMultipleProtocolInterfaces (\r
633 WinNtDevice->Handle,\r
634 &gEfiDevicePathProtocolGuid,\r
635 WinNtDevice->DevicePath,\r
636 &gEfiWinNtIoProtocolGuid,\r
637 &WinNtDevice->WinNtIo,\r
638 NULL\r
639 );\r
640\r
641 if (EFI_ERROR (Status)) {\r
642 gBS->OpenProtocol (\r
643 ControllerHandle,\r
644 &gEfiWinNtThunkProtocolGuid,\r
645 (VOID **) &WinNtThunk,\r
646 This->DriverBindingHandle,\r
647 WinNtDevice->Handle,\r
648 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
649 );\r
650 } else {\r
651 //\r
652 // Close the child handle\r
653 //\r
654 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);\r
655 gBS->FreePool (WinNtDevice);\r
656 }\r
657 }\r
658\r
659 if (EFI_ERROR (Status)) {\r
660 AllChildrenStopped = FALSE;\r
661 }\r
662 }\r
663\r
664 if (!AllChildrenStopped) {\r
665 return EFI_DEVICE_ERROR;\r
666 }\r
667\r
668 return EFI_SUCCESS;\r
669}\r
670\r
671EFI_DEVICE_PATH_PROTOCOL *\r
672WinNtBusCreateDevicePath (\r
673 IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,\r
674 IN EFI_GUID *Guid,\r
675 IN UINT16 InstanceNumber\r
676 )\r
677/*++\r
678\r
679Routine Description:\r
680 Create a device path node using Guid and InstanceNumber and append it to\r
681 the passed in RootDevicePath\r
682\r
683Arguments:\r
684 RootDevicePath - Root of the device path to return.\r
685\r
686 Guid - GUID to use in vendor device path node.\r
687\r
688 InstanceNumber - Instance number to use in the vendor device path. This\r
689 argument is needed to make sure each device path is unique.\r
690\r
691Returns:\r
692\r
7f0ceb22 693 EFI_DEVICE_PATH_PROTOCOL\r
878ddf1f 694\r
695--*/\r
696{\r
697 WIN_NT_VENDOR_DEVICE_PATH_NODE DevicePath;\r
698\r
699 DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;\r
700 DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;\r
701 SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE));\r
702\r
703 //\r
704 // The GUID defines the Class\r
705 //\r
706 CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));\r
707\r
708 //\r
709 // Add an instance number so we can make sure there are no Device Path\r
710 // duplication.\r
711 //\r
712 DevicePath.Instance = InstanceNumber;\r
713\r
714 return AppendDevicePathNode (\r
715 RootDevicePath,\r
716 (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath\r
717 );\r
718}\r