--- /dev/null
+/** @file\r
+ IsaIo UEFI driver.\r
+\r
+ Produce an instance of the ISA I/O Protocol for every SIO controller.\r
+ \r
+Copyright (c) 2010, 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
+**/\r
+\r
+#include "IsaDriver.h"\r
+\r
+//\r
+// IsaIo Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIsaIoDriver = {\r
+ IsaIoDriverSupported,\r
+ IsaIoDriverStart,\r
+ IsaIoDriverStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+/**\r
+ The main entry point for the IsaIo driver.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeIsaIo (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gIsaIoDriver,\r
+ ImageHandle,\r
+ &gIsaIoComponentName,\r
+ &gIsaIoComponentName2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/** \r
+ Tests to see if a controller can be managed by the IsaIo driver.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. \r
+ @param[in] Controller The handle of the controller to test.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.\r
+ \r
+ @retval EFI_SUCCESS The device is supported by this driver.\r
+ @retval EFI_ALREADY_STARTED The device is already being managed by this driver.\r
+ @retval EFI_ACCESS_DENIED The device is already being managed by a different driver \r
+ or an application that requires exclusive access.\r
+ @retval EFI_UNSUPPORTED The device is is not supported by this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_SIO_PROTOCOL *Sio;\r
+ EFI_HANDLE PciHandle;\r
+\r
+ //\r
+ // Try to open EFI DEVICE PATH protocol on the controller\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Get the PciIo protocol from its parent controller.\r
+ //\r
+ Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &DevicePath, &PciHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ if ((DevicePathType (DevicePath) != ACPI_DEVICE_PATH) ||\r
+ ((DevicePathSubType (DevicePath) != ACPI_DP) && (DevicePathSubType (DevicePath) != ACPI_EXTENDED_DP))) {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Try to open the Super IO protocol on the controller\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ (VOID **) &Sio,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Start this driver on ControllerHandle. \r
+ \r
+ The Start() function is designed to be invoked from the EFI boot service ConnectController(). \r
+ As a result, much of the error checking on the parameters to Start() has been moved into this \r
+ common boot service. It is legal to call Start() from other locations, but the following calling \r
+ restrictions must be followed or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE.\r
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+ EFI_DEVICE_PATH_PROTOCOL.\r
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. \r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle \r
+ must support a protocol interface that supplies \r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
+ This parameter is ignored by device drivers, and is optional for bus drivers.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
+ Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failded to start the device.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_HANDLE PciHandle;\r
+ EFI_SIO_PROTOCOL *Sio;\r
+ ACPI_RESOURCE_HEADER_PTR Resources;\r
+ EFI_DEVICE_PATH_PROTOCOL *AcpiNode;\r
+ ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+ PciIo = NULL;\r
+ Sio = NULL;\r
+\r
+ //\r
+ // Open Device Path Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the PciIo protocol from its parent controller.\r
+ //\r
+ AcpiNode = DevicePath;\r
+ Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &AcpiNode, &PciHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // AcpiNode should point to the ACPI node now.\r
+ //\r
+ ASSERT ((DevicePathType (AcpiNode) == ACPI_DEVICE_PATH) &&\r
+ ((DevicePathSubType (AcpiNode) == ACPI_DP) || (DevicePathSubType (AcpiNode) == ACPI_EXTENDED_DP))\r
+ );\r
+\r
+ Status = gBS->HandleProtocol (PciHandle, &gEfiPciIoProtocolGuid, &PciIo);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Open Super IO Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ (VOID **) &Sio,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Fail due to LocateDevicePath(...) or OpenProtocol(Sio, BY_DRIVER)\r
+ //\r
+ return Status;\r
+ }\r
+\r
+ Status = Sio->GetResources (Sio, &Resources);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ IsaIoDevice = AllocatePool (sizeof (ISA_IO_DEVICE));\r
+ ASSERT (IsaIoDevice != NULL);\r
+\r
+ IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;\r
+ IsaIoDevice->PciIo = PciIo;\r
+\r
+ //\r
+ // Initialize the ISA I/O instance structure\r
+ //\r
+ InitializeIsaIoInstance (IsaIoDevice, DevicePath, Resources);\r
+\r
+ //\r
+ // Install the ISA I/O protocol on the Controller handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ &IsaIoDevice->IsaIo,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Stop this driver on ControllerHandle. \r
+ \r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). \r
+ As a result, much of the error checking on the parameters to Stop() has been moved \r
+ into this common boot service. It is legal to call Stop() from other locations, \r
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+ \r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
+ support a bus specific I/O protocol for the driver \r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStop (\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
+ EFI_STATUS Status;\r
+ ISA_IO_DEVICE *IsaIoDevice;\r
+ EFI_ISA_IO_PROTOCOL *IsaIo;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ (VOID **) &IsaIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ &IsaIoDevice->IsaIo,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiSioProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ FreePool (IsaIoDevice->IsaIo.ResourceList);\r
+ FreePool (IsaIoDevice);\r
+ }\r
+\r
+ return Status;\r
+}
\ No newline at end of file