]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/WinNtBusDriverDxe/WinNtBusDriver.c
Update the copyright notice format
[mirror_edk2.git] / Nt32Pkg / WinNtBusDriverDxe / WinNtBusDriver.c
CommitLineData
6ae81428 1/**@file\r
420fc8e5 2\r
8f2a5f80
HT
3Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials\r
420fc8e5 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
11\r
12Module Name:\r
13\r
14 WinNtBusDriver.c\r
15\r
16Abstract:\r
17\r
18This following section documents the envirnoment variables for the Win NT\r
19build. These variables are used to define the (virtual) hardware\r
20configuration of the NT environment\r
21\r
22A ! can be used to seperate multiple instances in a variable. Each\r
23instance represents a seperate hardware device.\r
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
62409219 29EFI_WIN_NT_GOP - Builds GOP Windows of Width and Height\r
420fc8e5 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
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
42 used to seperate multiple devices in a variable.\r
43\r
44 EFI_WIN_NT_VIRTUAL_DISKS =\r
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
51 media device.\r
52\r
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
67 EFI_WIN_NT_FILE_SYSTEM =\r
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
73 EFI_WIN_NT_CONSOLE =\r
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
62409219 79 EFI_WIN_NT_GOP =\r
420fc8e5 80 <width> <height>[!...]\r
81\r
62409219 82 Declaring a two GOP windows with resolutions of 800x600 and 1024x768 would look like:\r
83 Example : EFI_WIN_NT_GOP=800 600!1024 768\r
420fc8e5 84\r
85 EFI_WIN_NT_SERIAL_PORT =\r
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//\r
101// The package level header files this module uses\r
102//\r
103#include <Uefi.h>\r
104#include <WinNtDxe.h>\r
105//\r
106// The protocols, PPI and GUID defintions for this module\r
107//\r
108#include <Protocol/WinNtThunk.h>\r
109#include <Protocol/WinNtIo.h>\r
110#include <Protocol/ComponentName.h>\r
111#include <Protocol/DriverBinding.h>\r
112#include <Protocol/DevicePath.h>\r
113//\r
114// The Library classes this module consumes\r
115//\r
116#include <Library/DebugLib.h>\r
117#include <Library/BaseLib.h>\r
118#include <Library/UefiDriverEntryPoint.h>\r
119#include <Library/UefiLib.h>\r
120#include <Library/PcdLib.h>\r
121#include <Library/BaseMemoryLib.h>\r
122#include <Library/UefiBootServicesTableLib.h>\r
123#include <Library/DevicePathLib.h>\r
124#include <Library/MemoryAllocationLib.h>\r
125\r
126#include "WinNtBusDriver.h"\r
127\r
128extern EFI_GUID gWinNtBusDriverGuid;\r
129//\r
130// DriverBinding protocol global\r
131//\r
132EFI_DRIVER_BINDING_PROTOCOL gWinNtBusDriverBinding = {\r
133 WinNtBusDriverBindingSupported,\r
134 WinNtBusDriverBindingStart,\r
135 WinNtBusDriverBindingStop,\r
136 0xa,\r
137 NULL,\r
138 NULL\r
139};\r
140\r
cba9012a 141#define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))\r
420fc8e5 142\r
143//\r
144// Table to map NT Environment variable to the GUID that should be in\r
145// device path.\r
146//\r
78e570b6 147NT_PCD_ENTRY mPcdEnvironment[] = {\r
cba9012a 148 PcdToken(PcdWinNtConsole), &gEfiWinNtConsoleGuid,\r
149 PcdToken(PcdWinNtGop), &gEfiWinNtGopGuid,\r
150 PcdToken(PcdWinNtSerialPort), &gEfiWinNtSerialPortGuid,\r
151 PcdToken(PcdWinNtFileSystem), &gEfiWinNtFileSystemGuid,\r
152 PcdToken(PcdWinNtVirtualDisk), &gEfiWinNtVirtualDisksGuid,\r
b397fbbb 153 PcdToken(PcdWinNtPhysicalDisk), &gEfiWinNtPhysicalDisksGuid\r
420fc8e5 154};\r
155\r
156/**\r
157 The user Entry Point for module WinNtBusDriver. The user code starts with this function.\r
158\r
62409219 159 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
420fc8e5 160 @param[in] SystemTable A pointer to the EFI System Table.\r
62409219 161\r
420fc8e5 162 @retval EFI_SUCCESS The entry point is executed successfully.\r
163 @retval other Some error occurs when executing this entry point.\r
164\r
165**/\r
166EFI_STATUS\r
167EFIAPI\r
168InitializeWinNtBusDriver(\r
169 IN EFI_HANDLE ImageHandle,\r
170 IN EFI_SYSTEM_TABLE *SystemTable\r
171 )\r
172{\r
173 EFI_STATUS Status;\r
174\r
175 //\r
176 // Install driver model protocol(s).\r
177 //\r
e1107a76 178 Status = EfiLibInstallDriverBindingComponentName2 (\r
420fc8e5 179 ImageHandle,\r
180 SystemTable,\r
181 &gWinNtBusDriverBinding,\r
182 ImageHandle,\r
183 &gWinNtBusDriverComponentName,\r
e1107a76 184 &gWinNtBusDriverComponentName2\r
420fc8e5 185 );\r
186 ASSERT_EFI_ERROR (Status);\r
187\r
188\r
189 return Status;\r
190}\r
191\r
192VOID *\r
193AllocateMemory (\r
194 IN UINTN Size\r
195 )\r
196{\r
197 VOID *Buffer;\r
198\r
199 Buffer = AllocatePool (Size);\r
200 ASSERT (Buffer != NULL);\r
201\r
202 return Buffer;\r
203}\r
204\r
205\r
206EFI_STATUS\r
207EFIAPI\r
208WinNtBusDriverBindingSupported (\r
209 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
210 IN EFI_HANDLE ControllerHandle,\r
211 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
212 )\r
213/*++\r
214\r
215Routine Description:\r
216\r
217Arguments:\r
218\r
219Returns:\r
220\r
221 None\r
222\r
6ae81428 223**/\r
420fc8e5 224// TODO: This - add argument and description to function comment\r
225// TODO: ControllerHandle - add argument and description to function comment\r
226// TODO: RemainingDevicePath - add argument and description to function comment\r
227// TODO: EFI_UNSUPPORTED - add return value to function comment\r
228// TODO: EFI_UNSUPPORTED - add return value to function comment\r
229// TODO: EFI_SUCCESS - add return value to function comment\r
230// TODO: EFI_SUCCESS - add return value to function comment\r
231{\r
232 EFI_STATUS Status;\r
233 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
234 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
235 UINTN Index;\r
236\r
237 //\r
238 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure\r
239 // it is a legal Device Path Node for this bus driver's children.\r
240 //\r
241 if (RemainingDevicePath != NULL) {\r
af4a6385 242 //\r
243 // Check if RemainingDevicePath is the End of Device Path Node, \r
244 // if yes, go on checking other conditions\r
245 //\r
246 if (!IsDevicePathEnd (RemainingDevicePath)) {\r
247 //\r
248 // If RemainingDevicePath isn't the End of Device Path Node,\r
249 // check its validation\r
250 //\r
251 if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||\r
252 RemainingDevicePath->SubType != HW_VENDOR_DP ||\r
253 DevicePathNodeLength(RemainingDevicePath) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE)) {\r
254 return EFI_UNSUPPORTED;\r
255 }\r
256 \r
257 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {\r
258 if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {\r
259 break;\r
260 }\r
261 }\r
262 \r
263 if (Index >= NT_PCD_ARRAY_SIZE) {\r
264 return EFI_UNSUPPORTED;\r
420fc8e5 265 }\r
420fc8e5 266 }\r
267 }\r
268\r
269 //\r
270 // Open the IO Abstraction(s) needed to perform the supported test\r
271 //\r
272 Status = gBS->OpenProtocol (\r
273 ControllerHandle,\r
af4a6385 274 &gEfiWinNtThunkProtocolGuid,\r
275 (VOID **) &WinNtThunk,\r
420fc8e5 276 This->DriverBindingHandle,\r
277 ControllerHandle,\r
278 EFI_OPEN_PROTOCOL_BY_DRIVER\r
279 );\r
280 if (Status == EFI_ALREADY_STARTED) {\r
281 return EFI_SUCCESS;\r
282 }\r
283\r
284 if (EFI_ERROR (Status)) {\r
285 return Status;\r
286 }\r
287\r
af4a6385 288 //\r
289 // Close the I/O Abstraction(s) used to perform the supported test\r
290 //\r
420fc8e5 291 gBS->CloseProtocol (\r
292 ControllerHandle,\r
af4a6385 293 &gEfiWinNtThunkProtocolGuid,\r
420fc8e5 294 This->DriverBindingHandle,\r
295 ControllerHandle\r
296 );\r
297\r
af4a6385 298 //\r
299 // Open the EFI Device Path protocol needed to perform the supported test\r
300 //\r
420fc8e5 301 Status = gBS->OpenProtocol (\r
302 ControllerHandle,\r
af4a6385 303 &gEfiDevicePathProtocolGuid,\r
304 (VOID **) &ParentDevicePath,\r
420fc8e5 305 This->DriverBindingHandle,\r
306 ControllerHandle,\r
307 EFI_OPEN_PROTOCOL_BY_DRIVER\r
308 );\r
309 if (Status == EFI_ALREADY_STARTED) {\r
310 return EFI_SUCCESS;\r
311 }\r
312\r
313 if (EFI_ERROR (Status)) {\r
314 return Status;\r
315 }\r
316\r
317 //\r
318 // Since we call through WinNtThunk we need to make sure it's valid\r
319 //\r
320 Status = EFI_SUCCESS;\r
321 if (WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {\r
322 Status = EFI_UNSUPPORTED;\r
323 }\r
324\r
325 //\r
af4a6385 326 // Close protocol, don't use device path protocol in the Support() function\r
420fc8e5 327 //\r
328 gBS->CloseProtocol (\r
329 ControllerHandle,\r
af4a6385 330 &gEfiDevicePathProtocolGuid,\r
420fc8e5 331 This->DriverBindingHandle,\r
332 ControllerHandle\r
333 );\r
334\r
335 return Status;\r
336}\r
337\r
338EFI_STATUS\r
339EFIAPI\r
340WinNtBusDriverBindingStart (\r
341 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
342 IN EFI_HANDLE ControllerHandle,\r
343 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
344 )\r
345/*++\r
346\r
347Routine Description:\r
348\r
349Arguments:\r
350\r
351Returns:\r
352\r
353 None\r
354\r
355--*/\r
356// TODO: This - add argument and description to function comment\r
357// TODO: ControllerHandle - add argument and description to function comment\r
358// TODO: RemainingDevicePath - add argument and description to function comment\r
359// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
360// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
361// TODO: EFI_SUCCESS - add return value to function comment\r
362{\r
363 EFI_STATUS Status;\r
420fc8e5 364 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
365 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
366 WIN_NT_BUS_DEVICE *WinNtBusDevice;\r
367 WIN_NT_IO_DEVICE *WinNtDevice;\r
368 UINTN Index;\r
369 CHAR16 *StartString;\r
370 CHAR16 *SubString;\r
371 UINT16 Count;\r
372 UINTN StringSize;\r
373 UINT16 ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];\r
374 WIN_NT_VENDOR_DEVICE_PATH_NODE *Node;\r
375 BOOLEAN CreateDevice;\r
376 CHAR16 *TempStr;\r
377 CHAR16 *PcdTempStr;\r
378 UINTN TempStrSize;\r
379\r
380 Status = EFI_UNSUPPORTED;\r
381\r
382 //\r
383 // Grab the protocols we need\r
384 //\r
385 Status = gBS->OpenProtocol (\r
386 ControllerHandle,\r
387 &gEfiDevicePathProtocolGuid,\r
3d6b07b6 388 (VOID **) &ParentDevicePath,\r
420fc8e5 389 This->DriverBindingHandle,\r
390 ControllerHandle,\r
391 EFI_OPEN_PROTOCOL_BY_DRIVER\r
392 );\r
393 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
394 return Status;\r
395 }\r
396\r
397 Status = gBS->OpenProtocol (\r
398 ControllerHandle,\r
399 &gEfiWinNtThunkProtocolGuid,\r
3d6b07b6 400 (VOID **) &WinNtThunk,\r
420fc8e5 401 This->DriverBindingHandle,\r
402 ControllerHandle,\r
403 EFI_OPEN_PROTOCOL_BY_DRIVER\r
404 );\r
405 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
406 return Status;\r
407 }\r
408\r
409 if (Status != EFI_ALREADY_STARTED) {\r
410 WinNtBusDevice = AllocatePool (sizeof (WIN_NT_BUS_DEVICE));\r
411 if (WinNtBusDevice == NULL) {\r
412 return EFI_OUT_OF_RESOURCES;\r
413 }\r
414\r
415 WinNtBusDevice->Signature = WIN_NT_BUS_DEVICE_SIGNATURE;\r
416 WinNtBusDevice->ControllerNameTable = NULL;\r
417\r
e1107a76 418 AddUnicodeString2 (\r
420fc8e5 419 "eng",\r
420 gWinNtBusDriverComponentName.SupportedLanguages,\r
421 &WinNtBusDevice->ControllerNameTable,\r
e1107a76 422 L"Windows Bus Controller",\r
423 TRUE\r
420fc8e5 424 );\r
e1107a76 425 AddUnicodeString2 (\r
426 "en",\r
427 gWinNtBusDriverComponentName2.SupportedLanguages,\r
428 &WinNtBusDevice->ControllerNameTable,\r
429 L"Windows Bus Controller",\r
430 FALSE\r
431 );\r
432\r
420fc8e5 433\r
434 Status = gBS->InstallMultipleProtocolInterfaces (\r
435 &ControllerHandle,\r
436 &gWinNtBusDriverGuid,\r
437 WinNtBusDevice,\r
438 NULL\r
439 );\r
440 if (EFI_ERROR (Status)) {\r
441 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);\r
442 FreePool (WinNtBusDevice);\r
443 return Status;\r
444 }\r
445 }\r
446\r
447 //\r
448 // Loop on the Variable list. Parse each variable to produce a set of handles that\r
449 // represent virtual hardware devices.\r
450 //\r
420fc8e5 451 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {\r
cba9012a 452 PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);\r
420fc8e5 453 ASSERT (PcdTempStr != NULL);\r
454\r
455 TempStrSize = StrLen (PcdTempStr);\r
456 TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);\r
457 StrCpy (TempStr, PcdTempStr);\r
458\r
459 StartString = TempStr;\r
460\r
461 //\r
462 // Parse the envirnment variable into sub strings using '!' as a delimator.\r
463 // Each substring needs it's own handle to be added to the system. This code\r
464 // does not understand the sub string. Thats the device drivers job.\r
465 //\r
466 Count = 0;\r
467 while (*StartString != '\0') {\r
468\r
469 //\r
470 // Find the end of the sub string\r
471 //\r
472 SubString = StartString;\r
473 while (*SubString != '\0' && *SubString != '!') {\r
474 SubString++;\r
475 }\r
476\r
477 if (*SubString == '!') {\r
478 //\r
479 // Replace token with '\0' to make sub strings. If this is the end\r
480 // of the string SubString will already point to NULL.\r
481 //\r
482 *SubString = '\0';\r
483 SubString++;\r
484 }\r
485\r
486 CreateDevice = TRUE;\r
487 if (RemainingDevicePath != NULL) {\r
488 CreateDevice = FALSE;\r
af4a6385 489 //\r
490 // Check if RemainingDevicePath is the End of Device Path Node, \r
491 // if yes, don't create any child device \r
492 //\r
493 if (!IsDevicePathEnd (RemainingDevicePath)) {\r
494 //\r
495 // If RemainingDevicePath isn't the End of Device Path Node,\r
496 // check its validation\r
497 //\r
498 Node = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;\r
499 if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&\r
500 Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&\r
501 DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)\r
420fc8e5 502 ) {\r
af4a6385 503 if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&\r
504 Node->Instance == Count\r
505 ) {\r
506 CreateDevice = TRUE;\r
507 }\r
420fc8e5 508 }\r
509 }\r
510 }\r
511\r
512 if (CreateDevice) {\r
513\r
514 //\r
515 // Allocate instance structure, and fill in parent information.\r
516 //\r
517 WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));\r
518 if (WinNtDevice == NULL) {\r
519 return EFI_OUT_OF_RESOURCES;\r
520 }\r
521\r
522 WinNtDevice->Handle = NULL;\r
523 WinNtDevice->ControllerHandle = ControllerHandle;\r
524 WinNtDevice->ParentDevicePath = ParentDevicePath;\r
525\r
526 WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;\r
527\r
528 //\r
529 // Plus 2 to account for the NULL at the end of the Unicode string\r
530 //\r
531 StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);\r
532 WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);\r
533 if (WinNtDevice->WinNtIo.EnvString != NULL) {\r
534 CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);\r
535 }\r
536\r
537 WinNtDevice->ControllerNameTable = NULL;\r
538\r
539 WinNtThunk->SPrintf (ComponentName, sizeof (ComponentName), L"%s", WinNtDevice->WinNtIo.EnvString);\r
540\r
541 WinNtDevice->DevicePath = WinNtBusCreateDevicePath (\r
542 ParentDevicePath,\r
543 mPcdEnvironment[Index].DevicePathGuid,\r
544 Count\r
545 );\r
546 if (WinNtDevice->DevicePath == NULL) {\r
547 FreePool (WinNtDevice);\r
548 return EFI_OUT_OF_RESOURCES;\r
549 }\r
550\r
e1107a76 551 AddUnicodeString2 (\r
420fc8e5 552 "eng",\r
553 gWinNtBusDriverComponentName.SupportedLanguages,\r
554 &WinNtDevice->ControllerNameTable,\r
e1107a76 555 ComponentName,\r
556 TRUE\r
420fc8e5 557 );\r
e1107a76 558 AddUnicodeString2 (\r
559 "en",\r
560 gWinNtBusDriverComponentName2.SupportedLanguages,\r
561 &WinNtDevice->ControllerNameTable,\r
562 ComponentName,\r
563 FALSE\r
564 );\r
565\r
420fc8e5 566\r
567 WinNtDevice->WinNtIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;\r
568 WinNtDevice->WinNtIo.InstanceNumber = Count;\r
569\r
570 WinNtDevice->Signature = WIN_NT_IO_DEVICE_SIGNATURE;\r
571\r
572 Status = gBS->InstallMultipleProtocolInterfaces (\r
573 &WinNtDevice->Handle,\r
574 &gEfiDevicePathProtocolGuid,\r
575 WinNtDevice->DevicePath,\r
576 &gEfiWinNtIoProtocolGuid,\r
577 &WinNtDevice->WinNtIo,\r
578 NULL\r
579 );\r
580 if (EFI_ERROR (Status)) {\r
581 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);\r
582 FreePool (WinNtDevice);\r
583 } else {\r
584 //\r
585 // Open For Child Device\r
586 //\r
587 Status = gBS->OpenProtocol (\r
588 ControllerHandle,\r
589 &gEfiWinNtThunkProtocolGuid,\r
3d6b07b6 590 (VOID **) &WinNtThunk,\r
420fc8e5 591 This->DriverBindingHandle,\r
592 WinNtDevice->Handle,\r
593 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
594 );\r
420fc8e5 595 }\r
596 }\r
597\r
598 //\r
599 // Parse Next sub string. This will point to '\0' if we are at the end.\r
600 //\r
601 Count++;\r
602 StartString = SubString;\r
603 }\r
604\r
605 FreePool (TempStr);\r
606 }\r
607\r
608 return EFI_SUCCESS;\r
609}\r
610\r
611\r
612EFI_STATUS\r
613EFIAPI\r
614WinNtBusDriverBindingStop (\r
615 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
616 IN EFI_HANDLE ControllerHandle,\r
617 IN UINTN NumberOfChildren,\r
618 IN EFI_HANDLE *ChildHandleBuffer\r
619 )\r
620/*++\r
621\r
622Routine Description:\r
623\r
624Arguments:\r
625\r
626Returns:\r
627\r
628 None\r
629\r
630--*/\r
631// TODO: This - add argument and description to function comment\r
632// TODO: ControllerHandle - add argument and description to function comment\r
633// TODO: NumberOfChildren - add argument and description to function comment\r
634// TODO: ChildHandleBuffer - add argument and description to function comment\r
635// TODO: EFI_SUCCESS - add return value to function comment\r
636// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
637// TODO: EFI_SUCCESS - add return value to function comment\r
638{\r
639 EFI_STATUS Status;\r
640 UINTN Index;\r
641 BOOLEAN AllChildrenStopped;\r
642 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;\r
643 WIN_NT_BUS_DEVICE *WinNtBusDevice;\r
644 WIN_NT_IO_DEVICE *WinNtDevice;\r
645 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;\r
646\r
647 //\r
648 // Complete all outstanding transactions to Controller.\r
649 // Don't allow any new transaction to Controller to be started.\r
650 //\r
651\r
652 if (NumberOfChildren == 0) {\r
653 //\r
654 // Close the bus driver\r
655 //\r
656 Status = gBS->OpenProtocol (\r
657 ControllerHandle,\r
658 &gWinNtBusDriverGuid,\r
3d6b07b6 659 (VOID **) &WinNtBusDevice,\r
420fc8e5 660 This->DriverBindingHandle,\r
661 ControllerHandle,\r
662 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
663 );\r
664 if (EFI_ERROR (Status)) {\r
665 return Status;\r
666 }\r
667\r
668 gBS->UninstallMultipleProtocolInterfaces (\r
669 ControllerHandle,\r
670 &gWinNtBusDriverGuid,\r
671 WinNtBusDevice,\r
672 NULL\r
673 );\r
674\r
675 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);\r
676\r
677 FreePool (WinNtBusDevice);\r
678\r
679 gBS->CloseProtocol (\r
680 ControllerHandle,\r
681 &gEfiWinNtThunkProtocolGuid,\r
682 This->DriverBindingHandle,\r
683 ControllerHandle\r
684 );\r
685\r
686 gBS->CloseProtocol (\r
687 ControllerHandle,\r
688 &gEfiDevicePathProtocolGuid,\r
689 This->DriverBindingHandle,\r
690 ControllerHandle\r
691 );\r
692 return EFI_SUCCESS;\r
693 }\r
694\r
695 AllChildrenStopped = TRUE;\r
696\r
697 for (Index = 0; Index < NumberOfChildren; Index++) {\r
698\r
699 Status = gBS->OpenProtocol (\r
700 ChildHandleBuffer[Index],\r
701 &gEfiWinNtIoProtocolGuid,\r
3d6b07b6 702 (VOID **) &WinNtIo,\r
420fc8e5 703 This->DriverBindingHandle,\r
704 ControllerHandle,\r
705 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
706 );\r
707 if (!EFI_ERROR (Status)) {\r
708\r
709 WinNtDevice = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);\r
710\r
711 Status = gBS->CloseProtocol (\r
712 ControllerHandle,\r
713 &gEfiWinNtThunkProtocolGuid,\r
714 This->DriverBindingHandle,\r
715 WinNtDevice->Handle\r
716 );\r
717\r
718 Status = gBS->UninstallMultipleProtocolInterfaces (\r
719 WinNtDevice->Handle,\r
720 &gEfiDevicePathProtocolGuid,\r
721 WinNtDevice->DevicePath,\r
722 &gEfiWinNtIoProtocolGuid,\r
723 &WinNtDevice->WinNtIo,\r
724 NULL\r
725 );\r
726\r
727 if (EFI_ERROR (Status)) {\r
728 gBS->OpenProtocol (\r
729 ControllerHandle,\r
730 &gEfiWinNtThunkProtocolGuid,\r
731 (VOID **) &WinNtThunk,\r
732 This->DriverBindingHandle,\r
733 WinNtDevice->Handle,\r
734 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
735 );\r
736 } else {\r
737 //\r
738 // Close the child handle\r
739 //\r
740 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);\r
741 FreePool (WinNtDevice);\r
742 }\r
743 }\r
744\r
745 if (EFI_ERROR (Status)) {\r
746 AllChildrenStopped = FALSE;\r
747 }\r
748 }\r
749\r
750 if (!AllChildrenStopped) {\r
751 return EFI_DEVICE_ERROR;\r
752 }\r
753\r
754 return EFI_SUCCESS;\r
755}\r
756\r
757EFI_DEVICE_PATH_PROTOCOL *\r
758WinNtBusCreateDevicePath (\r
759 IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,\r
760 IN EFI_GUID *Guid,\r
761 IN UINT16 InstanceNumber\r
762 )\r
763/*++\r
764\r
765Routine Description:\r
766 Create a device path node using Guid and InstanceNumber and append it to\r
767 the passed in RootDevicePath\r
768\r
769Arguments:\r
770 RootDevicePath - Root of the device path to return.\r
771\r
772 Guid - GUID to use in vendor device path node.\r
773\r
774 InstanceNumber - Instance number to use in the vendor device path. This\r
775 argument is needed to make sure each device path is unique.\r
776\r
777Returns:\r
778\r
779 EFI_DEVICE_PATH_PROTOCOL\r
780\r
781--*/\r
782{\r
783 WIN_NT_VENDOR_DEVICE_PATH_NODE DevicePath;\r
784\r
785 DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;\r
786 DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;\r
787 SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE));\r
788\r
789 //\r
790 // The GUID defines the Class\r
791 //\r
792 CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));\r
793\r
794 //\r
795 // Add an instance number so we can make sure there are no Device Path\r
796 // duplication.\r
797 //\r
798 DevicePath.Instance = InstanceNumber;\r
799\r
800 return AppendDevicePathNode (\r
801 RootDevicePath,\r
802 (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath\r
803 );\r
804}\r