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