+++ /dev/null
-/*+++\r
-\r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- UnixBusDriver.c\r
-\r
-Abstract:\r
-\r
-This following section documents the environment variables for the UNIX \r
-build. These variables are used to define the (virtual) hardware \r
-configuration of the UNIX environment\r
-\r
-A ! can be used to seperate multiple instances in a variable. Each \r
-instance represents a seperate hardware device. \r
-\r
-EFI_UNIX_PHYSICAL_DISKS - maps to drives on your system\r
-EFI_UNIX_VIRTUAL_DISKS - maps to a device emulated by a file\r
-EFI_UNIX_FILE_SYSTEM - mouts a directory as a file system\r
-EFI_UNIX_CONSOLE - make a logical comand line window (only one!)\r
-EFI_UNIX_UGA - Builds UGA Windows of Width and Height\r
-\r
- <F>ixed - Fixed disk like a hard drive.\r
- <R>emovable - Removable media like a floppy or CD-ROM.\r
- Read <O>nly - Write protected device.\r
- Read <W>rite - Read write device.\r
- <block count> - Decimal number of blocks a device supports.\r
- <block size> - Decimal number of bytes per block.\r
-\r
- UNIX envirnonment variable contents. '<' and '>' are not part of the variable, \r
- they are just used to make this help more readable. There should be no \r
- spaces between the ';'. Extra spaces will break the variable. A '!' is \r
- used to seperate multiple devices in a variable.\r
-\r
- EFI_UNIX_VIRTUAL_DISKS = \r
- <F | R><O | W>;<block count>;<block size>[!...]\r
-\r
- EFI_UNIX_PHYSICAL_DISKS =\r
- <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]\r
-\r
- Virtual Disks: These devices use a file to emulate a hard disk or removable\r
- media device. \r
- \r
- Thus a 20 MB emulated hard drive would look like:\r
- EFI_UNIX_VIRTUAL_DISKS=FW;40960;512\r
-\r
- A 1.44MB emulated floppy with a block size of 1024 would look like:\r
- EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024\r
-\r
- Physical Disks: These devices use UNIX to open a real device in your system\r
-\r
- Thus a 120 MB floppy would look like:\r
- EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512\r
-\r
- Thus a standard CD-ROM floppy would look like:\r
- EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048\r
-\r
- EFI_UNIX_FILE_SYSTEM = \r
- <directory path>[!...]\r
-\r
- Mounting the two directories C:\FOO and C:\BAR would look like:\r
- EFI_UNIX_FILE_SYSTEM=c:\foo!c:\bar\r
-\r
- EFI_UNIX_CONSOLE = \r
- <window title>\r
-\r
- Declaring a text console window with the title "My EFI Console" woild look like:\r
- EFI_UNIX_CONSOLE=My EFI Console\r
-\r
- EFI_UNIX_UGA = \r
- <width> <height>[!...]\r
-\r
- Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:\r
- Example : EFI_UNIX_UGA=800 600!1024 768\r
-\r
- EFI_UNIX_PASS_THROUGH =\r
- <BaseAddress>;<Bus#>;<Device#>;<Function#>\r
-\r
- Declaring a base address of 0xE0000000 (used for PCI Express devices)\r
- and having NT32 talk to a device located at bus 0, device 1, function 0:\r
- Example : EFI_UNIX_PASS_THROUGH=E000000;0;1;0\r
-\r
----*/\r
-\r
-#include "UnixBusDriver.h"\r
-\r
-//\r
-// Define GUID for the Unix Bus Driver\r
-//\r
-EFI_GUID gUnixBusDriverGuid = {\r
- 0x419f582, 0x625, 0x4531, {0x8a, 0x33, 0x85, 0xa9, 0x96, 0x5c, 0x95, 0xbc}\r
-};\r
-\r
-//\r
-// DriverBinding protocol global\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gUnixBusDriverBinding = {\r
- UnixBusDriverBindingSupported,\r
- UnixBusDriverBindingStart,\r
- UnixBusDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-#define UNIX_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(UNIX_PCD_ENTRY))\r
-\r
-//\r
-// Table to map UNIX Environment variable to the GUID that should be in\r
-// device path.\r
-//\r
-UNIX_PCD_ENTRY mPcdEnvironment[] = {\r
- {PcdToken(PcdUnixConsole), &gEfiUnixConsoleGuid},\r
- {PcdToken(PcdUnixUga), &gEfiUnixUgaGuid},\r
- {PcdToken(PcdUnixGop), &gEfiUnixGopGuid},\r
- {PcdToken(PcdUnixFileSystem), &gEfiUnixFileSystemGuid},\r
- {PcdToken(PcdUnixSerialPort), &gEfiUnixSerialPortGuid},\r
- {PcdToken(PcdUnixVirtualDisk), &gEfiUnixVirtualDisksGuid},\r
- {PcdToken(PcdUnixPhysicalDisk), &gEfiUnixPhysicalDisksGuid},\r
- {PcdToken(PcdUnixCpuModel), &gEfiUnixCPUModelGuid},\r
- {PcdToken(PcdUnixCpuSpeed), &gEfiUnixCPUSpeedGuid},\r
- {PcdToken(PcdUnixMemorySize), &gEfiUnixMemoryGuid},\r
- {PcdToken(PcdUnixNetworkInterface), &gEfiUnixNetworkGuid}\r
-};\r
-\r
-VOID *\r
-AllocateMemory (\r
- IN UINTN Size\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *Buffer;\r
-\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- Size,\r
- (VOID *)&Buffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (FALSE);\r
- return NULL;\r
- }\r
- return Buffer;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBusDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_UNIX_THUNK_PROTOCOL *UnixThunk;\r
- UINTN Index;\r
-\r
- //\r
- // Check the contents of the first Device Path Node of RemainingDevicePath to make sure\r
- // it is a legal Device Path Node for this bus driver's children.\r
- //\r
- if (RemainingDevicePath != NULL) {\r
- //\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
- // if yes, go on checking other conditions\r
- //\r
- if (!IsDevicePathEnd (RemainingDevicePath)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node,\r
- // check its validation\r
- //\r
- if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||\r
- RemainingDevicePath->SubType != HW_VENDOR_DP ||\r
- DevicePathNodeLength(RemainingDevicePath) != sizeof(UNIX_VENDOR_DEVICE_PATH_NODE)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {\r
- if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {\r
- break;\r
- }\r
- }\r
- \r
- if (Index >= UNIX_PCD_ARRAY_SIZE) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
- \r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- (VOID **)&UnixThunk,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Close the I/O Abstraction(s) used to perform the supported test\r
- //\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- //\r
- // Open the EFI Device Path protocol needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **)&ParentDevicePath,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (Status == EFI_ALREADY_STARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Since we call through UnixThunk we need to make sure it's valid\r
- //\r
- Status = EFI_SUCCESS;\r
- if (UnixThunk->Signature != EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {\r
- Status = EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Close protocol, don't use device path protocol in the Support() function\r
- //\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBusDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS InstallStatus;\r
- EFI_UNIX_THUNK_PROTOCOL *UnixThunk;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- UNIX_BUS_DEVICE *UnixBusDevice;\r
- UNIX_IO_DEVICE *UnixDevice;\r
- UINTN Index;\r
- CHAR16 *StartString;\r
- CHAR16 *SubString;\r
- UINT16 Count;\r
- UINTN StringSize;\r
- UINT16 ComponentName[MAX_UNIX_ENVIRNMENT_VARIABLE_LENGTH];\r
- UNIX_VENDOR_DEVICE_PATH_NODE *Node;\r
- BOOLEAN CreateDevice;\r
- CHAR16 *TempStr;\r
- CHAR16 *PcdTempStr;\r
- UINTN TempStrSize;\r
-\r
- Status = EFI_UNSUPPORTED;\r
-\r
- //\r
- // Grab the protocols we need\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **)&ParentDevicePath,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- (VOID **)&UnixThunk,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
- return Status;\r
- }\r
-\r
- if (Status != EFI_ALREADY_STARTED) {\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (UNIX_BUS_DEVICE),\r
- (VOID *) &UnixBusDevice\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- UnixBusDevice->Signature = UNIX_BUS_DEVICE_SIGNATURE;\r
- UnixBusDevice->ControllerNameTable = NULL;\r
-\r
- AddUnicodeString (\r
- "eng",\r
- gUnixBusDriverComponentName.SupportedLanguages,\r
- &UnixBusDevice->ControllerNameTable,\r
- L"Unix Bus Controller"\r
- );\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &ControllerHandle,\r
- &gUnixBusDriverGuid,\r
- UnixBusDevice,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);\r
- gBS->FreePool (UnixBusDevice);\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Loop on the Variable list. Parse each variable to produce a set of handles that\r
- // represent virtual hardware devices.\r
- //\r
- InstallStatus = EFI_NOT_FOUND;\r
- for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {\r
- PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);\r
- ASSERT (PcdTempStr != NULL);\r
-\r
- TempStrSize = StrLen (PcdTempStr);\r
- TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);\r
- StrCpy (TempStr, PcdTempStr);\r
-\r
- StartString = TempStr;\r
-\r
- //\r
- // Parse the environment variable into sub strings using '!' as a delimator.\r
- // Each substring needs it's own handle to be added to the system. This code\r
- // does not understand the sub string. Thats the device drivers job.\r
- //\r
- Count = 0;\r
- while (*StartString != '\0') {\r
-\r
- //\r
- // Find the end of the sub string\r
- //\r
- SubString = StartString;\r
- while (*SubString != '\0' && *SubString != '!') {\r
- SubString++;\r
- }\r
-\r
- if (*SubString == '!') {\r
- //\r
- // Replace token with '\0' to make sub strings. If this is the end\r
- // of the string SubString will already point to NULL.\r
- //\r
- *SubString = '\0';\r
- SubString++;\r
- }\r
-\r
- CreateDevice = TRUE;\r
- if (RemainingDevicePath != NULL) {\r
- CreateDevice = FALSE;\r
- //\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
- // if yes, don't create any child device \r
- //\r
- if (!IsDevicePathEnd (RemainingDevicePath)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node,\r
- // check its validation\r
- //\r
- Node = (UNIX_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;\r
- if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&\r
- Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&\r
- DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (UNIX_VENDOR_DEVICE_PATH_NODE)\r
- ) {\r
- if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&\r
- Node->Instance == Count\r
- ) {\r
- CreateDevice = TRUE;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (CreateDevice) {\r
- //\r
- // Allocate instance structure, and fill in parent information.\r
- //\r
- UnixDevice = AllocateMemory (sizeof (UNIX_IO_DEVICE));\r
- if (UnixDevice == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- UnixDevice->Handle = NULL;\r
- UnixDevice->ControllerHandle = ControllerHandle;\r
- UnixDevice->ParentDevicePath = ParentDevicePath;\r
-\r
- UnixDevice->UnixIo.UnixThunk = UnixThunk;\r
-\r
- //\r
- // Plus 2 to account for the NULL at the end of the Unicode string\r
- //\r
- StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);\r
- UnixDevice->UnixIo.EnvString = AllocateMemory (StringSize);\r
- if (UnixDevice->UnixIo.EnvString != NULL) {\r
- CopyMem (UnixDevice->UnixIo.EnvString, StartString, StringSize);\r
- }\r
-\r
- UnixDevice->ControllerNameTable = NULL;\r
-\r
- // FIXME: check size\r
- StrCpy(ComponentName, UnixDevice->UnixIo.EnvString);\r
-\r
- UnixDevice->DevicePath = UnixBusCreateDevicePath (\r
- ParentDevicePath,\r
- mPcdEnvironment[Index].DevicePathGuid,\r
- Count\r
- );\r
- if (UnixDevice->DevicePath == NULL) {\r
- gBS->FreePool (UnixDevice);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- AddUnicodeString (\r
- "eng",\r
- gUnixBusDriverComponentName.SupportedLanguages,\r
- &UnixDevice->ControllerNameTable,\r
- ComponentName\r
- );\r
-\r
- UnixDevice->UnixIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;\r
- UnixDevice->UnixIo.InstanceNumber = Count;\r
-\r
- UnixDevice->Signature = UNIX_IO_DEVICE_SIGNATURE;\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &UnixDevice->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- UnixDevice->DevicePath,\r
- &gEfiUnixIoProtocolGuid,\r
- &UnixDevice->UnixIo,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FreeUnicodeStringTable (UnixDevice->ControllerNameTable);\r
- gBS->FreePool (UnixDevice);\r
- } else {\r
- //\r
- // Open For Child Device\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- (VOID **)&UnixThunk,\r
- This->DriverBindingHandle,\r
- UnixDevice->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- InstallStatus = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Parse Next sub string. This will point to '\0' if we are at the end.\r
- //\r
- Count++;\r
- StartString = SubString;\r
- }\r
-\r
- gBS->FreePool (TempStr);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UnixBusDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- BOOLEAN AllChildrenStopped;\r
- EFI_UNIX_IO_PROTOCOL *UnixIo;\r
- UNIX_BUS_DEVICE *UnixBusDevice;\r
- UNIX_IO_DEVICE *UnixDevice;\r
- EFI_UNIX_THUNK_PROTOCOL *UnixThunk;\r
-\r
- //\r
- // Complete all outstanding transactions to Controller.\r
- // Don't allow any new transaction to Controller to be started.\r
- //\r
-\r
- if (NumberOfChildren == 0) {\r
- //\r
- // Close the bus driver\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gUnixBusDriverGuid,\r
- (VOID **)&UnixBusDevice,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- ControllerHandle,\r
- &gUnixBusDriverGuid,\r
- UnixBusDevice,\r
- NULL\r
- );\r
-\r
- FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);\r
-\r
- gBS->FreePool (UnixBusDevice);\r
-\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- return EFI_SUCCESS;\r
- }\r
-\r
- AllChildrenStopped = TRUE;\r
-\r
- for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
- Status = gBS->OpenProtocol (\r
- ChildHandleBuffer[Index],\r
- &gEfiUnixIoProtocolGuid,\r
- (VOID **)&UnixIo,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
-\r
- UnixDevice = UNIX_IO_DEVICE_FROM_THIS (UnixIo);\r
-\r
- Status = gBS->CloseProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- This->DriverBindingHandle,\r
- UnixDevice->Handle\r
- );\r
-\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- UnixDevice->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- UnixDevice->DevicePath,\r
- &gEfiUnixIoProtocolGuid,\r
- &UnixDevice->UnixIo,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUnixThunkProtocolGuid,\r
- (VOID **) &UnixThunk,\r
- This->DriverBindingHandle,\r
- UnixDevice->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- } else {\r
- //\r
- // Close the child handle\r
- //\r
- FreeUnicodeStringTable (UnixDevice->ControllerNameTable);\r
- gBS->FreePool (UnixDevice);\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- AllChildrenStopped = FALSE;\r
- }\r
- }\r
-\r
- if (!AllChildrenStopped) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_DEVICE_PATH_PROTOCOL *\r
-UnixBusCreateDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,\r
- IN EFI_GUID *Guid,\r
- IN UINT16 InstanceNumber\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Create a device path node using Guid and InstanceNumber and append it to\r
- the passed in RootDevicePath\r
-\r
-Arguments:\r
- RootDevicePath - Root of the device path to return.\r
-\r
- Guid - GUID to use in vendor device path node.\r
-\r
- InstanceNumber - Instance number to use in the vendor device path. This\r
- argument is needed to make sure each device path is unique.\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_PATH_PROTOCOL \r
-\r
---*/\r
-{\r
- UNIX_VENDOR_DEVICE_PATH_NODE DevicePath;\r
-\r
- DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;\r
- DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;\r
- SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (UNIX_VENDOR_DEVICE_PATH_NODE));\r
-\r
- //\r
- // The GUID defines the Class\r
- //\r
- CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));\r
-\r
- //\r
- // Add an instance number so we can make sure there are no Device Path\r
- // duplication.\r
- //\r
- DevicePath.Instance = InstanceNumber;\r
-\r
- return AppendDevicePathNode (\r
- RootDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath\r
- );\r
-}\r