blob: 1516ab8d1c12ec6b2a06d96d9f65a74bee9bc3cb [file] [log] [blame]
klu26ae81422008-03-19 03:23:16 +00001/**@file
klu2420fc8e2007-06-27 05:46:08 +00002
hhtian8f2a5f82010-04-28 12:24:39 +00003Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
klu2420fc8e2007-06-27 05:46:08 +00005are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14 WinNtBusDriver.c
15
16Abstract:
17
18This following section documents the envirnoment variables for the Win NT
19build. These variables are used to define the (virtual) hardware
20configuration of the NT environment
21
22A ! can be used to seperate multiple instances in a variable. Each
23instance represents a seperate hardware device.
24
25EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system
26EFI_WIN_NT_VIRTUAL_DISKS - maps to a device emulated by a file
27EFI_WIN_NT_FILE_SYSTEM - mouts a directory as a file system
28EFI_WIN_NT_CONSOLE - make a logical comand line window (only one!)
vanjeff62409212007-10-17 06:55:15 +000029EFI_WIN_NT_GOP - Builds GOP Windows of Width and Height
klu2420fc8e2007-06-27 05:46:08 +000030EFI_WIN_NT_SERIAL_PORT - maps physical serial ports
31
32 <F>ixed - Fixed disk like a hard drive.
33 <R>emovable - Removable media like a floppy or CD-ROM.
34 Read <O>nly - Write protected device.
35 Read <W>rite - Read write device.
36 <block count> - Decimal number of blocks a device supports.
37 <block size> - Decimal number of bytes per block.
38
39 NT envirnonment variable contents. '<' and '>' are not part of the variable,
40 they are just used to make this help more readable. There should be no
41 spaces between the ';'. Extra spaces will break the variable. A '!' is
42 used to seperate multiple devices in a variable.
43
44 EFI_WIN_NT_VIRTUAL_DISKS =
45 <F | R><O | W>;<block count>;<block size>[!...]
46
47 EFI_WIN_NT_PHYSICAL_DISKS =
48 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
49
50 Virtual Disks: These devices use a file to emulate a hard disk or removable
51 media device.
52
53 Thus a 20 MB emulated hard drive would look like:
54 EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512
55
56 A 1.44MB emulated floppy with a block size of 1024 would look like:
57 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024
58
59 Physical Disks: These devices use NT to open a real device in your system
60
61 Thus a 120 MB floppy would look like:
62 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512
63
64 Thus a standard CD-ROM floppy would look like:
65 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048
66
67 EFI_WIN_NT_FILE_SYSTEM =
68 <directory path>[!...]
69
70 Mounting the two directories C:\FOO and C:\BAR would look like:
71 EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar
72
73 EFI_WIN_NT_CONSOLE =
74 <window title>
75
76 Declaring a text console window with the title "My EFI Console" woild look like:
77 EFI_WIN_NT_CONSOLE=My EFI Console
78
vanjeff62409212007-10-17 06:55:15 +000079 EFI_WIN_NT_GOP =
klu2420fc8e2007-06-27 05:46:08 +000080 <width> <height>[!...]
81
vanjeff62409212007-10-17 06:55:15 +000082 Declaring a two GOP windows with resolutions of 800x600 and 1024x768 would look like:
83 Example : EFI_WIN_NT_GOP=800 600!1024 768
klu2420fc8e2007-06-27 05:46:08 +000084
85 EFI_WIN_NT_SERIAL_PORT =
86 <port name>[!...]
87
88 Declaring two serial ports on COM1 and COM2 would look like:
89 Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2
90
91 EFI_WIN_NT_PASS_THROUGH =
92 <BaseAddress>;<Bus#>;<Device#>;<Function#>
93
94 Declaring a base address of 0xE0000000 (used for PCI Express devices)
95 and having NT32 talk to a device located at bus 0, device 1, function 0:
96 Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0
97
98---*/
99
100//
101// The package level header files this module uses
102//
103#include <Uefi.h>
104#include <WinNtDxe.h>
105//
106// The protocols, PPI and GUID defintions for this module
107//
108#include <Protocol/WinNtThunk.h>
109#include <Protocol/WinNtIo.h>
110#include <Protocol/ComponentName.h>
111#include <Protocol/DriverBinding.h>
112#include <Protocol/DevicePath.h>
113//
114// The Library classes this module consumes
115//
116#include <Library/DebugLib.h>
117#include <Library/BaseLib.h>
118#include <Library/UefiDriverEntryPoint.h>
119#include <Library/UefiLib.h>
120#include <Library/PcdLib.h>
121#include <Library/BaseMemoryLib.h>
122#include <Library/UefiBootServicesTableLib.h>
123#include <Library/DevicePathLib.h>
124#include <Library/MemoryAllocationLib.h>
125
126#include "WinNtBusDriver.h"
127
128extern EFI_GUID gWinNtBusDriverGuid;
129//
130// DriverBinding protocol global
131//
132EFI_DRIVER_BINDING_PROTOCOL gWinNtBusDriverBinding = {
133 WinNtBusDriverBindingSupported,
134 WinNtBusDriverBindingStart,
135 WinNtBusDriverBindingStop,
136 0xa,
137 NULL,
138 NULL
139};
140
klu2cba90122007-07-10 08:57:25 +0000141#define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))
klu2420fc8e2007-06-27 05:46:08 +0000142
143//
144// Table to map NT Environment variable to the GUID that should be in
145// device path.
146//
jji478e570b2008-10-30 06:11:42 +0000147NT_PCD_ENTRY mPcdEnvironment[] = {
klu2cba90122007-07-10 08:57:25 +0000148 PcdToken(PcdWinNtConsole), &gEfiWinNtConsoleGuid,
149 PcdToken(PcdWinNtGop), &gEfiWinNtGopGuid,
150 PcdToken(PcdWinNtSerialPort), &gEfiWinNtSerialPortGuid,
151 PcdToken(PcdWinNtFileSystem), &gEfiWinNtFileSystemGuid,
152 PcdToken(PcdWinNtVirtualDisk), &gEfiWinNtVirtualDisksGuid,
AJFISHb397fbb2007-07-26 21:33:37 +0000153 PcdToken(PcdWinNtPhysicalDisk), &gEfiWinNtPhysicalDisksGuid
klu2420fc8e2007-06-27 05:46:08 +0000154};
155
156/**
157 The user Entry Point for module WinNtBusDriver. The user code starts with this function.
158
vanjeff62409212007-10-17 06:55:15 +0000159 @param[in] ImageHandle The firmware allocated handle for the EFI image.
klu2420fc8e2007-06-27 05:46:08 +0000160 @param[in] SystemTable A pointer to the EFI System Table.
vanjeff62409212007-10-17 06:55:15 +0000161
klu2420fc8e2007-06-27 05:46:08 +0000162 @retval EFI_SUCCESS The entry point is executed successfully.
163 @retval other Some error occurs when executing this entry point.
164
165**/
166EFI_STATUS
167EFIAPI
168InitializeWinNtBusDriver(
169 IN EFI_HANDLE ImageHandle,
170 IN EFI_SYSTEM_TABLE *SystemTable
171 )
172{
173 EFI_STATUS Status;
174
175 //
176 // Install driver model protocol(s).
177 //
qhuang8e1107a72007-09-29 11:20:23 +0000178 Status = EfiLibInstallDriverBindingComponentName2 (
klu2420fc8e2007-06-27 05:46:08 +0000179 ImageHandle,
180 SystemTable,
181 &gWinNtBusDriverBinding,
182 ImageHandle,
183 &gWinNtBusDriverComponentName,
qhuang8e1107a72007-09-29 11:20:23 +0000184 &gWinNtBusDriverComponentName2
klu2420fc8e2007-06-27 05:46:08 +0000185 );
186 ASSERT_EFI_ERROR (Status);
187
188
189 return Status;
190}
191
192VOID *
193AllocateMemory (
194 IN UINTN Size
195 )
196{
197 VOID *Buffer;
198
199 Buffer = AllocatePool (Size);
200 ASSERT (Buffer != NULL);
201
202 return Buffer;
203}
204
205
206EFI_STATUS
207EFIAPI
208WinNtBusDriverBindingSupported (
209 IN EFI_DRIVER_BINDING_PROTOCOL *This,
210 IN EFI_HANDLE ControllerHandle,
211 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
212 )
213/*++
214
215Routine Description:
216
217Arguments:
218
219Returns:
220
221 None
222
klu26ae81422008-03-19 03:23:16 +0000223**/
klu2420fc8e2007-06-27 05:46:08 +0000224// TODO: This - add argument and description to function comment
225// TODO: ControllerHandle - add argument and description to function comment
226// TODO: RemainingDevicePath - add argument and description to function comment
227// TODO: EFI_UNSUPPORTED - add return value to function comment
228// TODO: EFI_UNSUPPORTED - add return value to function comment
229// TODO: EFI_SUCCESS - add return value to function comment
230// TODO: EFI_SUCCESS - add return value to function comment
231{
232 EFI_STATUS Status;
233 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
234 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
235 UINTN Index;
236
237 //
238 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
239 // it is a legal Device Path Node for this bus driver's children.
240 //
241 if (RemainingDevicePath != NULL) {
vanjeffaf4a6382009-09-14 08:55:03 +0000242 //
243 // Check if RemainingDevicePath is the End of Device Path Node,
244 // if yes, go on checking other conditions
245 //
246 if (!IsDevicePathEnd (RemainingDevicePath)) {
247 //
248 // If RemainingDevicePath isn't the End of Device Path Node,
249 // check its validation
250 //
251 if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
252 RemainingDevicePath->SubType != HW_VENDOR_DP ||
253 DevicePathNodeLength(RemainingDevicePath) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE)) {
254 return EFI_UNSUPPORTED;
klu2420fc8e2007-06-27 05:46:08 +0000255 }
vanjeffaf4a6382009-09-14 08:55:03 +0000256
257 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {
258 if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {
259 break;
260 }
261 }
262
263 if (Index >= NT_PCD_ARRAY_SIZE) {
264 return EFI_UNSUPPORTED;
265 }
klu2420fc8e2007-06-27 05:46:08 +0000266 }
267 }
268
269 //
270 // Open the IO Abstraction(s) needed to perform the supported test
271 //
272 Status = gBS->OpenProtocol (
273 ControllerHandle,
vanjeffaf4a6382009-09-14 08:55:03 +0000274 &gEfiWinNtThunkProtocolGuid,
275 (VOID **) &WinNtThunk,
klu2420fc8e2007-06-27 05:46:08 +0000276 This->DriverBindingHandle,
277 ControllerHandle,
278 EFI_OPEN_PROTOCOL_BY_DRIVER
279 );
280 if (Status == EFI_ALREADY_STARTED) {
281 return EFI_SUCCESS;
282 }
283
284 if (EFI_ERROR (Status)) {
285 return Status;
286 }
287
vanjeffaf4a6382009-09-14 08:55:03 +0000288 //
289 // Close the I/O Abstraction(s) used to perform the supported test
290 //
klu2420fc8e2007-06-27 05:46:08 +0000291 gBS->CloseProtocol (
292 ControllerHandle,
vanjeffaf4a6382009-09-14 08:55:03 +0000293 &gEfiWinNtThunkProtocolGuid,
klu2420fc8e2007-06-27 05:46:08 +0000294 This->DriverBindingHandle,
295 ControllerHandle
296 );
297
vanjeffaf4a6382009-09-14 08:55:03 +0000298 //
299 // Open the EFI Device Path protocol needed to perform the supported test
300 //
klu2420fc8e2007-06-27 05:46:08 +0000301 Status = gBS->OpenProtocol (
302 ControllerHandle,
vanjeffaf4a6382009-09-14 08:55:03 +0000303 &gEfiDevicePathProtocolGuid,
304 (VOID **) &ParentDevicePath,
klu2420fc8e2007-06-27 05:46:08 +0000305 This->DriverBindingHandle,
306 ControllerHandle,
307 EFI_OPEN_PROTOCOL_BY_DRIVER
308 );
309 if (Status == EFI_ALREADY_STARTED) {
310 return EFI_SUCCESS;
311 }
312
313 if (EFI_ERROR (Status)) {
314 return Status;
315 }
316
317 //
318 // Since we call through WinNtThunk we need to make sure it's valid
319 //
320 Status = EFI_SUCCESS;
321 if (WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {
322 Status = EFI_UNSUPPORTED;
323 }
324
325 //
vanjeffaf4a6382009-09-14 08:55:03 +0000326 // Close protocol, don't use device path protocol in the Support() function
klu2420fc8e2007-06-27 05:46:08 +0000327 //
328 gBS->CloseProtocol (
329 ControllerHandle,
vanjeffaf4a6382009-09-14 08:55:03 +0000330 &gEfiDevicePathProtocolGuid,
klu2420fc8e2007-06-27 05:46:08 +0000331 This->DriverBindingHandle,
332 ControllerHandle
333 );
334
335 return Status;
336}
337
338EFI_STATUS
339EFIAPI
340WinNtBusDriverBindingStart (
341 IN EFI_DRIVER_BINDING_PROTOCOL *This,
342 IN EFI_HANDLE ControllerHandle,
343 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
344 )
345/*++
346
347Routine Description:
348
349Arguments:
350
351Returns:
352
353 None
354
355--*/
356// TODO: This - add argument and description to function comment
357// TODO: ControllerHandle - add argument and description to function comment
358// TODO: RemainingDevicePath - add argument and description to function comment
359// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
360// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
361// TODO: EFI_SUCCESS - add return value to function comment
362{
363 EFI_STATUS Status;
klu2420fc8e2007-06-27 05:46:08 +0000364 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
365 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
366 WIN_NT_BUS_DEVICE *WinNtBusDevice;
367 WIN_NT_IO_DEVICE *WinNtDevice;
368 UINTN Index;
369 CHAR16 *StartString;
370 CHAR16 *SubString;
371 UINT16 Count;
372 UINTN StringSize;
373 UINT16 ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];
374 WIN_NT_VENDOR_DEVICE_PATH_NODE *Node;
375 BOOLEAN CreateDevice;
376 CHAR16 *TempStr;
377 CHAR16 *PcdTempStr;
378 UINTN TempStrSize;
379
380 Status = EFI_UNSUPPORTED;
381
382 //
383 // Grab the protocols we need
384 //
385 Status = gBS->OpenProtocol (
386 ControllerHandle,
387 &gEfiDevicePathProtocolGuid,
qwang123d6b07b2008-10-30 15:10:52 +0000388 (VOID **) &ParentDevicePath,
klu2420fc8e2007-06-27 05:46:08 +0000389 This->DriverBindingHandle,
390 ControllerHandle,
391 EFI_OPEN_PROTOCOL_BY_DRIVER
392 );
393 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
394 return Status;
395 }
396
397 Status = gBS->OpenProtocol (
398 ControllerHandle,
399 &gEfiWinNtThunkProtocolGuid,
qwang123d6b07b2008-10-30 15:10:52 +0000400 (VOID **) &WinNtThunk,
klu2420fc8e2007-06-27 05:46:08 +0000401 This->DriverBindingHandle,
402 ControllerHandle,
403 EFI_OPEN_PROTOCOL_BY_DRIVER
404 );
405 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
406 return Status;
407 }
408
409 if (Status != EFI_ALREADY_STARTED) {
410 WinNtBusDevice = AllocatePool (sizeof (WIN_NT_BUS_DEVICE));
411 if (WinNtBusDevice == NULL) {
412 return EFI_OUT_OF_RESOURCES;
413 }
414
415 WinNtBusDevice->Signature = WIN_NT_BUS_DEVICE_SIGNATURE;
416 WinNtBusDevice->ControllerNameTable = NULL;
417
qhuang8e1107a72007-09-29 11:20:23 +0000418 AddUnicodeString2 (
klu2420fc8e2007-06-27 05:46:08 +0000419 "eng",
420 gWinNtBusDriverComponentName.SupportedLanguages,
421 &WinNtBusDevice->ControllerNameTable,
qhuang8e1107a72007-09-29 11:20:23 +0000422 L"Windows Bus Controller",
423 TRUE
klu2420fc8e2007-06-27 05:46:08 +0000424 );
qhuang8e1107a72007-09-29 11:20:23 +0000425 AddUnicodeString2 (
426 "en",
427 gWinNtBusDriverComponentName2.SupportedLanguages,
428 &WinNtBusDevice->ControllerNameTable,
429 L"Windows Bus Controller",
430 FALSE
431 );
432
klu2420fc8e2007-06-27 05:46:08 +0000433
434 Status = gBS->InstallMultipleProtocolInterfaces (
435 &ControllerHandle,
436 &gWinNtBusDriverGuid,
437 WinNtBusDevice,
438 NULL
439 );
440 if (EFI_ERROR (Status)) {
441 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);
442 FreePool (WinNtBusDevice);
443 return Status;
444 }
445 }
446
447 //
448 // Loop on the Variable list. Parse each variable to produce a set of handles that
449 // represent virtual hardware devices.
450 //
klu2420fc8e2007-06-27 05:46:08 +0000451 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {
klu2cba90122007-07-10 08:57:25 +0000452 PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);
klu2420fc8e2007-06-27 05:46:08 +0000453 ASSERT (PcdTempStr != NULL);
454
455 TempStrSize = StrLen (PcdTempStr);
456 TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);
457 StrCpy (TempStr, PcdTempStr);
458
459 StartString = TempStr;
460
461 //
462 // Parse the envirnment variable into sub strings using '!' as a delimator.
463 // Each substring needs it's own handle to be added to the system. This code
464 // does not understand the sub string. Thats the device drivers job.
465 //
466 Count = 0;
467 while (*StartString != '\0') {
468
469 //
470 // Find the end of the sub string
471 //
472 SubString = StartString;
473 while (*SubString != '\0' && *SubString != '!') {
474 SubString++;
475 }
476
477 if (*SubString == '!') {
478 //
479 // Replace token with '\0' to make sub strings. If this is the end
480 // of the string SubString will already point to NULL.
481 //
482 *SubString = '\0';
483 SubString++;
484 }
485
486 CreateDevice = TRUE;
487 if (RemainingDevicePath != NULL) {
488 CreateDevice = FALSE;
vanjeffaf4a6382009-09-14 08:55:03 +0000489 //
490 // Check if RemainingDevicePath is the End of Device Path Node,
491 // if yes, don't create any child device
492 //
493 if (!IsDevicePathEnd (RemainingDevicePath)) {
494 //
495 // If RemainingDevicePath isn't the End of Device Path Node,
496 // check its validation
497 //
498 Node = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
499 if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
500 Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
501 DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)
klu2420fc8e2007-06-27 05:46:08 +0000502 ) {
vanjeffaf4a6382009-09-14 08:55:03 +0000503 if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&
504 Node->Instance == Count
505 ) {
506 CreateDevice = TRUE;
507 }
klu2420fc8e2007-06-27 05:46:08 +0000508 }
509 }
510 }
511
512 if (CreateDevice) {
513
514 //
515 // Allocate instance structure, and fill in parent information.
516 //
517 WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));
518 if (WinNtDevice == NULL) {
519 return EFI_OUT_OF_RESOURCES;
520 }
521
522 WinNtDevice->Handle = NULL;
523 WinNtDevice->ControllerHandle = ControllerHandle;
524 WinNtDevice->ParentDevicePath = ParentDevicePath;
525
526 WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;
527
528 //
529 // Plus 2 to account for the NULL at the end of the Unicode string
530 //
531 StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);
532 WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);
533 if (WinNtDevice->WinNtIo.EnvString != NULL) {
534 CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);
535 }
536
537 WinNtDevice->ControllerNameTable = NULL;
538
539 WinNtThunk->SPrintf (ComponentName, sizeof (ComponentName), L"%s", WinNtDevice->WinNtIo.EnvString);
540
541 WinNtDevice->DevicePath = WinNtBusCreateDevicePath (
542 ParentDevicePath,
543 mPcdEnvironment[Index].DevicePathGuid,
544 Count
545 );
546 if (WinNtDevice->DevicePath == NULL) {
547 FreePool (WinNtDevice);
548 return EFI_OUT_OF_RESOURCES;
549 }
550
qhuang8e1107a72007-09-29 11:20:23 +0000551 AddUnicodeString2 (
klu2420fc8e2007-06-27 05:46:08 +0000552 "eng",
553 gWinNtBusDriverComponentName.SupportedLanguages,
554 &WinNtDevice->ControllerNameTable,
qhuang8e1107a72007-09-29 11:20:23 +0000555 ComponentName,
556 TRUE
klu2420fc8e2007-06-27 05:46:08 +0000557 );
qhuang8e1107a72007-09-29 11:20:23 +0000558 AddUnicodeString2 (
559 "en",
560 gWinNtBusDriverComponentName2.SupportedLanguages,
561 &WinNtDevice->ControllerNameTable,
562 ComponentName,
563 FALSE
564 );
565
klu2420fc8e2007-06-27 05:46:08 +0000566
567 WinNtDevice->WinNtIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;
568 WinNtDevice->WinNtIo.InstanceNumber = Count;
569
570 WinNtDevice->Signature = WIN_NT_IO_DEVICE_SIGNATURE;
571
572 Status = gBS->InstallMultipleProtocolInterfaces (
573 &WinNtDevice->Handle,
574 &gEfiDevicePathProtocolGuid,
575 WinNtDevice->DevicePath,
576 &gEfiWinNtIoProtocolGuid,
577 &WinNtDevice->WinNtIo,
578 NULL
579 );
580 if (EFI_ERROR (Status)) {
581 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);
582 FreePool (WinNtDevice);
583 } else {
584 //
585 // Open For Child Device
586 //
587 Status = gBS->OpenProtocol (
588 ControllerHandle,
589 &gEfiWinNtThunkProtocolGuid,
qwang123d6b07b2008-10-30 15:10:52 +0000590 (VOID **) &WinNtThunk,
klu2420fc8e2007-06-27 05:46:08 +0000591 This->DriverBindingHandle,
592 WinNtDevice->Handle,
593 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
594 );
klu2420fc8e2007-06-27 05:46:08 +0000595 }
596 }
597
598 //
599 // Parse Next sub string. This will point to '\0' if we are at the end.
600 //
601 Count++;
602 StartString = SubString;
603 }
604
605 FreePool (TempStr);
606 }
607
608 return EFI_SUCCESS;
609}
610
611
612EFI_STATUS
613EFIAPI
614WinNtBusDriverBindingStop (
615 IN EFI_DRIVER_BINDING_PROTOCOL *This,
616 IN EFI_HANDLE ControllerHandle,
617 IN UINTN NumberOfChildren,
618 IN EFI_HANDLE *ChildHandleBuffer
619 )
620/*++
621
622Routine Description:
623
624Arguments:
625
626Returns:
627
628 None
629
630--*/
631// TODO: This - add argument and description to function comment
632// TODO: ControllerHandle - add argument and description to function comment
633// TODO: NumberOfChildren - add argument and description to function comment
634// TODO: ChildHandleBuffer - add argument and description to function comment
635// TODO: EFI_SUCCESS - add return value to function comment
636// TODO: EFI_DEVICE_ERROR - add return value to function comment
637// TODO: EFI_SUCCESS - add return value to function comment
638{
639 EFI_STATUS Status;
640 UINTN Index;
641 BOOLEAN AllChildrenStopped;
642 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;
643 WIN_NT_BUS_DEVICE *WinNtBusDevice;
644 WIN_NT_IO_DEVICE *WinNtDevice;
645 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
646
647 //
648 // Complete all outstanding transactions to Controller.
649 // Don't allow any new transaction to Controller to be started.
650 //
651
652 if (NumberOfChildren == 0) {
653 //
654 // Close the bus driver
655 //
656 Status = gBS->OpenProtocol (
657 ControllerHandle,
658 &gWinNtBusDriverGuid,
qwang123d6b07b2008-10-30 15:10:52 +0000659 (VOID **) &WinNtBusDevice,
klu2420fc8e2007-06-27 05:46:08 +0000660 This->DriverBindingHandle,
661 ControllerHandle,
662 EFI_OPEN_PROTOCOL_GET_PROTOCOL
663 );
664 if (EFI_ERROR (Status)) {
665 return Status;
666 }
667
668 gBS->UninstallMultipleProtocolInterfaces (
669 ControllerHandle,
670 &gWinNtBusDriverGuid,
671 WinNtBusDevice,
672 NULL
673 );
674
675 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);
676
677 FreePool (WinNtBusDevice);
678
679 gBS->CloseProtocol (
680 ControllerHandle,
681 &gEfiWinNtThunkProtocolGuid,
682 This->DriverBindingHandle,
683 ControllerHandle
684 );
685
686 gBS->CloseProtocol (
687 ControllerHandle,
688 &gEfiDevicePathProtocolGuid,
689 This->DriverBindingHandle,
690 ControllerHandle
691 );
692 return EFI_SUCCESS;
693 }
694
695 AllChildrenStopped = TRUE;
696
697 for (Index = 0; Index < NumberOfChildren; Index++) {
698
699 Status = gBS->OpenProtocol (
700 ChildHandleBuffer[Index],
701 &gEfiWinNtIoProtocolGuid,
qwang123d6b07b2008-10-30 15:10:52 +0000702 (VOID **) &WinNtIo,
klu2420fc8e2007-06-27 05:46:08 +0000703 This->DriverBindingHandle,
704 ControllerHandle,
705 EFI_OPEN_PROTOCOL_GET_PROTOCOL
706 );
707 if (!EFI_ERROR (Status)) {
708
709 WinNtDevice = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);
710
711 Status = gBS->CloseProtocol (
712 ControllerHandle,
713 &gEfiWinNtThunkProtocolGuid,
714 This->DriverBindingHandle,
715 WinNtDevice->Handle
716 );
717
718 Status = gBS->UninstallMultipleProtocolInterfaces (
719 WinNtDevice->Handle,
720 &gEfiDevicePathProtocolGuid,
721 WinNtDevice->DevicePath,
722 &gEfiWinNtIoProtocolGuid,
723 &WinNtDevice->WinNtIo,
724 NULL
725 );
726
727 if (EFI_ERROR (Status)) {
728 gBS->OpenProtocol (
729 ControllerHandle,
730 &gEfiWinNtThunkProtocolGuid,
731 (VOID **) &WinNtThunk,
732 This->DriverBindingHandle,
733 WinNtDevice->Handle,
734 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
735 );
736 } else {
737 //
738 // Close the child handle
739 //
740 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);
741 FreePool (WinNtDevice);
742 }
743 }
744
745 if (EFI_ERROR (Status)) {
746 AllChildrenStopped = FALSE;
747 }
748 }
749
750 if (!AllChildrenStopped) {
751 return EFI_DEVICE_ERROR;
752 }
753
754 return EFI_SUCCESS;
755}
756
757EFI_DEVICE_PATH_PROTOCOL *
758WinNtBusCreateDevicePath (
759 IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
760 IN EFI_GUID *Guid,
761 IN UINT16 InstanceNumber
762 )
763/*++
764
765Routine Description:
766 Create a device path node using Guid and InstanceNumber and append it to
767 the passed in RootDevicePath
768
769Arguments:
770 RootDevicePath - Root of the device path to return.
771
772 Guid - GUID to use in vendor device path node.
773
774 InstanceNumber - Instance number to use in the vendor device path. This
775 argument is needed to make sure each device path is unique.
776
777Returns:
778
779 EFI_DEVICE_PATH_PROTOCOL
780
781--*/
782{
783 WIN_NT_VENDOR_DEVICE_PATH_NODE DevicePath;
784
785 DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;
786 DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;
787 SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE));
788
789 //
790 // The GUID defines the Class
791 //
792 CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));
793
794 //
795 // Add an instance number so we can make sure there are no Device Path
796 // duplication.
797 //
798 DevicePath.Instance = InstanceNumber;
799
800 return AppendDevicePathNode (
801 RootDevicePath,
802 (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
803 );
804}