--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR> \r
+This software and associated documentation (if any) is furnished\r
+under a license and may only be used or copied in accordance\r
+with the terms of the license. Except as permitted by such\r
+license, no part of this software or documentation may be\r
+reproduced, stored in a retrieval system, or transmitted in any\r
+form or by any means without the express written consent of\r
+Intel Corporation.\r
+\r
+Module Name:\r
+\r
+ IsaBus.c\r
+ \r
+Abstract:\r
+\r
+ Discovers all the ISA Controllers and their resources by using the ISA PnP \r
+ Protocol, produces an instance of the ISA I/O Protocol for every ISA \r
+ Controller found, loads and initializes all ISA Device Drivers, matches ISA\r
+ Device Drivers with their respective ISA Controllers in a deterministic \r
+ manner, and informs a ISA Device Driver when it is to start managing an ISA\r
+ Controller. \r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+#include "InternalIsaBus.h"\r
+\r
+//\r
+// ISA Bus Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver = {\r
+ IsaBusControllerDriverSupported,\r
+ IsaBusControllerDriverStart,\r
+ IsaBusControllerDriverStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+IsaBusControllerDriverSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ This function checks to see if a controller can be managed by the ISA Bus \r
+ Driver. This is done by checking to see if the controller supports the \r
+ EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration \r
+ Header to see if the device is a PCI to ISA bridge. The class code of \r
+ PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h \r
+ \r
+ Arguments:\r
+ \r
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ Controller - The handle of the device to check.\r
+ RemainingDevicePath - A pointer to the remaining portion of a device path.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS - The device is supported by this driver.\r
+ EFI_UNSUPPORTED - The device is not supported by this driver.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
+\r
+ //\r
+ // If RemainingDevicePath is not NULL, it should verify that the first device\r
+ // path node in RemainingDevicePath is an ACPI Device path node\r
+ //\r
+ if (RemainingDevicePath != NULL) {\r
+ if (RemainingDevicePath->Type != ACPI_DEVICE_PATH) {\r
+ return EFI_UNSUPPORTED;\r
+ } else if (RemainingDevicePath->SubType == ACPI_DP) {\r
+ if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else if (RemainingDevicePath->SubType == ACPI_EXTENDED_DP) {\r
+ if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ //\r
+ // Test the existence of DEVICE_PATH protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Get the Isa Acpi protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIsaAcpiProtocolGuid,\r
+ (VOID **) &IsaAcpi,\r
+ This->DriverBindingHandle,\r
+ Controller,\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
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIsaAcpiProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+IsaBusControllerDriverStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ This function tells the ISA Bus Driver to start managing a PCI to ISA \r
+ Bridge controller. \r
+ \r
+ Arguments:\r
+ \r
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ Controller - A handle to the device being started. \r
+ RemainingDevicePath - A pointer to the remaining portion of a device path.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS - The device was started.\r
+ EFI_UNSUPPORTED - The device is not supported.\r
+ EFI_DEVICE_ERROR - The device could not be started due to a device error.\r
+ EFI_ALREADY_STARTED - The device has already been started.\r
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
+ resources.\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
+ EFI_ISA_ACPI_DEVICE_ID *IsaDevice;\r
+ EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;\r
+ EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;\r
+\r
+ //\r
+ // Local variables declaration for StatusCode reporting\r
+ //\r
+ EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathData;\r
+\r
+ BootScriptSaveInformationAsciiString (\r
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,\r
+ "IsaBusBindingStartBegin"\r
+ );\r
+\r
+ //\r
+ // Initialize status code structure\r
+ //\r
+ AllocFailExtendedData.DataHeader.HeaderSize = sizeof (EFI_STATUS_CODE_DATA);\r
+ AllocFailExtendedData.DataHeader.Size = sizeof (EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA) - sizeof (EFI_STATUS_CODE_DATA);\r
+ CopyMem (\r
+ &AllocFailExtendedData.DataHeader.Type,\r
+ &gEfiStatusCodeSpecificDataGuid,\r
+ sizeof (EFI_GUID)\r
+ );\r
+\r
+ //\r
+ // Open Device Path Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Open Pci IO Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Close opened protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return Status;\r
+ }\r
+ //\r
+ // Open ISA Acpi Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIsaAcpiProtocolGuid,\r
+ (VOID **) &IsaAcpi,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ //\r
+ // Close opened protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return Status;\r
+ }\r
+ //\r
+ // The IsaBus driver will use memory below 16M, which is not tested yet,\r
+ // so call CompatibleRangeTest to test them. Since memory below 1M should\r
+ // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M\r
+ // ~15M here\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiGenericMemTestProtocolGuid,\r
+ NULL,\r
+ (VOID **) &GenMemoryTest\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = GenMemoryTest->CompatibleRangeTest (\r
+ GenMemoryTest,\r
+ 0x100000,\r
+ 0xE00000\r
+ );\r
+ }\r
+ //\r
+ // Report Status Code here since we will initialize the host controller\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // first init ISA interface\r
+ //\r
+ IsaAcpi->InterfaceInit (IsaAcpi);\r
+\r
+ //\r
+ // Report Status Code here since we will enable the host controller\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Create each ISA device handle in this ISA bus\r
+ //\r
+ IsaDevice = NULL;\r
+ do {\r
+ Status = IsaAcpi->DeviceEnumerate (IsaAcpi, &IsaDevice);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ //\r
+ // Get current resource of this ISA device\r
+ //\r
+ ResourceList = NULL;\r
+ Status = IsaAcpi->GetCurResource (IsaAcpi, IsaDevice, &ResourceList);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Create handle for this ISA device\r
+ //\r
+ Status = IsaCreateDevice (\r
+ This,\r
+ Controller,\r
+ PciIo,\r
+ ParentDevicePath,\r
+ ResourceList,\r
+ &DevicePathData\r
+ //&AllocFailExtendedData.DevicePath\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ //\r
+ // Initialize ISA device\r
+ //\r
+ IsaAcpi->InitDevice (IsaAcpi, IsaDevice);\r
+\r
+ //\r
+ // Set resources for this ISA device\r
+ //\r
+ Status = IsaAcpi->SetResource (IsaAcpi, IsaDevice, ResourceList);\r
+\r
+ //\r
+ // Report Status Code here when failed to resource conflicts\r
+ //\r
+ if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {\r
+ //\r
+ // It's hard to tell which resource conflicts\r
+ //\r
+ AllocFailExtendedData.Bar = 0;\r
+ AllocFailExtendedData.ReqRes = NULL;\r
+ AllocFailExtendedData.AllocRes = NULL;\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE,\r
+ (EFI_IO_BUS_LPC | EFI_IOB_EC_RESOURCE_CONFLICT),\r
+ DevicePathData\r
+ );\r
+\r
+ }\r
+ //\r
+ // Set power for this ISA device\r
+ //\r
+ IsaAcpi->SetPower (IsaAcpi, IsaDevice, TRUE);\r
+\r
+ //\r
+ // Enable this ISA device\r
+ //\r
+ IsaAcpi->EnableDevice (IsaAcpi, IsaDevice, TRUE);\r
+\r
+ } while (TRUE);\r
+\r
+ BootScriptSaveInformationAsciiString (\r
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,\r
+ "IsaBusBindingStartEnd"\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+IsaBusControllerDriverStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE * ChildHandleBuffer OPTIONAL\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ This function tells the ISA Bus Driver to stop managing a PCI to ISA \r
+ Bridge controller. \r
+ \r
+ Arguments:\r
+ \r
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ Controller - A handle to the device being stopped.\r
+ NumberOfChindren - The number of child device handles in ChildHandleBuffer.\r
+ ChildHandleBuffer - An array of child handles to be freed.\r
+\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS - The device was stopped.\r
+ EFI_DEVICE_ERROR - The device could not be stopped due to a device error.\r
+ EFI_NOT_STARTED - The device has not been started.\r
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
+ resources.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ BOOLEAN AllChildrenStopped;\r
+ ISA_IO_DEVICE *IsaIoDevice;\r
+ EFI_ISA_IO_PROTOCOL *IsaIo;\r
+\r
+ if (NumberOfChildren == 0) {\r
+ //\r
+ // Close the bus driver\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIsaAcpiProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // Complete all outstanding transactions to Controller.\r
+ // Don't allow any new transaction to Controller to be started.\r
+ //\r
+ //\r
+ // Stop all the children\r
+ // Find all the ISA devices that were discovered on this PCI to ISA Bridge\r
+ // with the Start() function.\r
+ //\r
+ AllChildrenStopped = TRUE;\r
+\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ChildHandleBuffer[Index],\r
+ &gEfiIsaIoProtocolGuid,\r
+ (VOID **) &IsaIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ ChildHandleBuffer[Index],\r
+ &gEfiDevicePathProtocolGuid,\r
+ IsaIoDevice->DevicePath,\r
+ &gEfiIsaIoProtocolGuid,\r
+ &IsaIoDevice->IsaIo,\r
+ NULL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Close the child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ ChildHandleBuffer[Index]\r
+ );\r
+\r
+ gBS->FreePool (IsaIoDevice->DevicePath);\r
+ gBS->FreePool (IsaIoDevice);\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
+// Internal Function\r
+//\r
+EFI_STATUS\r
+IsaCreateDevice (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList,\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **ChildDevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ Create ISA device found by IsaPnpProtocol \r
+\r
+ Arguments:\r
+ \r
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ Controller - The handle of ISA bus controller(PCI to ISA bridge)\r
+ PciIo - The Pointer to the PCI protocol \r
+ ParentDevicePath - Device path of the ISA bus controller\r
+ IsaDeviceResourceList - The resource list of the ISA device\r
+ ChildDevicePath - The pointer to the child device.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS - Create the child device.\r
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
+ resources.\r
+ EFI_DEVICE_ERROR - Can not create child device.\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ ISA_IO_DEVICE *IsaIoDevice;\r
+ EFI_DEV_PATH Node;\r
+\r
+ //\r
+ // Initialize the PCI_IO_DEVICE structure\r
+ //\r
+ IsaIoDevice = AllocateZeroPool (sizeof (ISA_IO_DEVICE));\r
+ if (IsaIoDevice == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;\r
+ IsaIoDevice->Handle = NULL;\r
+ IsaIoDevice->PciIo = PciIo;\r
+\r
+ //\r
+ // Initialize the ISA I/O instance structure\r
+ //\r
+ Status = InitializeIsaIoInstance (IsaIoDevice, IsaDeviceResourceList);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (IsaIoDevice);\r
+ return Status;\r
+ }\r
+ //\r
+ // Build the child device path\r
+ //\r
+ Node.DevPath.Type = ACPI_DEVICE_PATH;\r
+ Node.DevPath.SubType = ACPI_DP;\r
+ SetDevicePathNodeLength (&Node.DevPath, sizeof (ACPI_HID_DEVICE_PATH));\r
+ Node.Acpi.HID = IsaDeviceResourceList->Device.HID;\r
+ Node.Acpi.UID = IsaDeviceResourceList->Device.UID;\r
+\r
+ IsaIoDevice->DevicePath = AppendDevicePathNode (\r
+ ParentDevicePath,\r
+ &Node.DevPath\r
+ );\r
+\r
+ if (IsaIoDevice->DevicePath == NULL) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ *ChildDevicePath = IsaIoDevice->DevicePath;\r
+\r
+ //\r
+ // Create a child handle and attach the DevicePath,\r
+ // PCI I/O, and Controller State\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &IsaIoDevice->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IsaIoDevice->DevicePath,\r
+ &gEfiIsaIoProtocolGuid,\r
+ &IsaIoDevice->IsaIo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ IsaIoDevice->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ IsaIoDevice->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IsaIoDevice->DevicePath,\r
+ &gEfiIsaIoProtocolGuid,\r
+ &IsaIoDevice->IsaIo,\r
+ NULL\r
+ );\r
+ }\r
+\r
+Done:\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ if (IsaIoDevice->DevicePath != NULL) {\r
+ gBS->FreePool (IsaIoDevice->DevicePath);\r
+ }\r
+\r
+ gBS->FreePool (IsaIoDevice);\r
+ }\r
+\r
+ return Status;\r
+}\r