3 Discovers all the ISA Controllers and their resources by using the ISA PnP
4 Protocol, produces an instance of the ISA I/O Protocol for every ISA
5 Controller found, loads and initializes all ISA Device Drivers, matches ISA
6 Device Drivers with their respective ISA Controllers in a deterministic
7 manner, and informs a ISA Device Driver when it is to start managing an ISA
10 Copyright (c) 2006 - 2007, Intel Corporation.<BR>
11 All rights reserved. This program and the accompanying materials
12 are licensed and made available under the terms and conditions of the BSD License
13 which accompanies this distribution. The full text of the license may be found at
14 http://opensource.org/licenses/bsd-license.php
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include "InternalIsaBus.h"
25 // ISA Bus Driver Global Variables
27 EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver
= {
28 IsaBusControllerDriverSupported
,
29 IsaBusControllerDriverStart
,
30 IsaBusControllerDriverStop
,
37 The user Entry Point for module IsaBus. The user code starts with this function.
39 @param[in] ImageHandle The firmware allocated handle for the EFI image.
40 @param[in] SystemTable A pointer to the EFI System Table.
42 @retval EFI_SUCCESS The entry point is executed successfully.
43 @retval other Some error occurs when executing this entry point.
49 IN EFI_HANDLE ImageHandle
,
50 IN EFI_SYSTEM_TABLE
*SystemTable
56 // Install driver model protocol(s).
58 Status
= EfiLibInstallDriverBindingComponentName2 (
61 &gIsaBusControllerDriver
,
63 &gIsaBusComponentName
,
64 &gIsaBusComponentName2
66 ASSERT_EFI_ERROR (Status
);
75 IsaBusControllerDriverSupported (
76 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
77 IN EFI_HANDLE Controller
,
78 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
84 This function checks to see if a controller can be managed by the ISA Bus
85 Driver. This is done by checking to see if the controller supports the
86 EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration
87 Header to see if the device is a PCI to ISA bridge. The class code of
88 PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h
92 This - The EFI_DRIVER_BINDING_PROTOCOL instance.
93 Controller - The handle of the device to check.
94 RemainingDevicePath - A pointer to the remaining portion of a device path.
98 EFI_SUCCESS - The device is supported by this driver.
99 EFI_UNSUPPORTED - The device is not supported by this driver.
104 EFI_ISA_ACPI_PROTOCOL
*IsaAcpi
;
107 // If RemainingDevicePath is not NULL, it should verify that the first device
108 // path node in RemainingDevicePath is an ACPI Device path node
110 if (RemainingDevicePath
!= NULL
) {
111 if (RemainingDevicePath
->Type
!= ACPI_DEVICE_PATH
) {
112 return EFI_UNSUPPORTED
;
113 } else if (RemainingDevicePath
->SubType
== ACPI_DP
) {
114 if (DevicePathNodeLength (RemainingDevicePath
) != sizeof (ACPI_HID_DEVICE_PATH
)) {
115 return EFI_UNSUPPORTED
;
117 } else if (RemainingDevicePath
->SubType
== ACPI_EXTENDED_DP
) {
118 if (DevicePathNodeLength (RemainingDevicePath
) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH
)) {
119 return EFI_UNSUPPORTED
;
122 return EFI_UNSUPPORTED
;
126 // Test the existence of DEVICE_PATH protocol
128 Status
= gBS
->OpenProtocol (
130 &gEfiDevicePathProtocolGuid
,
132 This
->DriverBindingHandle
,
134 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
136 if (EFI_ERROR (Status
)) {
140 // Get the Isa Acpi protocol
142 Status
= gBS
->OpenProtocol (
144 &gEfiIsaAcpiProtocolGuid
,
146 This
->DriverBindingHandle
,
148 EFI_OPEN_PROTOCOL_BY_DRIVER
150 if (Status
== EFI_ALREADY_STARTED
) {
154 if (EFI_ERROR (Status
)) {
160 &gEfiIsaAcpiProtocolGuid
,
161 This
->DriverBindingHandle
,
170 IsaBusControllerDriverStart (
171 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
172 IN EFI_HANDLE Controller
,
173 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
179 This function tells the ISA Bus Driver to start managing a PCI to ISA
184 This - The EFI_DRIVER_BINDING_PROTOCOL instance.
185 Controller - A handle to the device being started.
186 RemainingDevicePath - A pointer to the remaining portion of a device path.
190 EFI_SUCCESS - The device was started.
191 EFI_UNSUPPORTED - The device is not supported.
192 EFI_DEVICE_ERROR - The device could not be started due to a device error.
193 EFI_ALREADY_STARTED - The device has already been started.
194 EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
195 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
201 EFI_PCI_IO_PROTOCOL
*PciIo
;
202 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
203 EFI_ISA_ACPI_PROTOCOL
*IsaAcpi
;
204 EFI_ISA_ACPI_DEVICE_ID
*IsaDevice
;
205 EFI_ISA_ACPI_RESOURCE_LIST
*ResourceList
;
206 EFI_GENERIC_MEMORY_TEST_PROTOCOL
*GenMemoryTest
;
209 // Local variables declaration for StatusCode reporting
211 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData
;
212 EFI_DEVICE_PATH_PROTOCOL
*DevicePathData
;
215 // Initialize status code structure
217 AllocFailExtendedData
.DataHeader
.HeaderSize
= sizeof (EFI_STATUS_CODE_DATA
);
218 AllocFailExtendedData
.DataHeader
.Size
= sizeof (EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA
) - sizeof (EFI_STATUS_CODE_DATA
);
220 &AllocFailExtendedData
.DataHeader
.Type
,
221 &gEfiStatusCodeSpecificDataGuid
,
226 // Open Device Path Protocol
228 Status
= gBS
->OpenProtocol (
230 &gEfiDevicePathProtocolGuid
,
231 (VOID
**) &ParentDevicePath
,
232 This
->DriverBindingHandle
,
234 EFI_OPEN_PROTOCOL_BY_DRIVER
236 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
240 // Open Pci IO Protocol
242 Status
= gBS
->OpenProtocol (
244 &gEfiPciIoProtocolGuid
,
246 This
->DriverBindingHandle
,
248 EFI_OPEN_PROTOCOL_GET_PROTOCOL
250 if (EFI_ERROR (Status
)) {
252 // Close opened protocol
256 &gEfiDevicePathProtocolGuid
,
257 This
->DriverBindingHandle
,
263 // Open ISA Acpi Protocol
265 Status
= gBS
->OpenProtocol (
267 &gEfiIsaAcpiProtocolGuid
,
269 This
->DriverBindingHandle
,
271 EFI_OPEN_PROTOCOL_BY_DRIVER
273 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
275 // Close opened protocol
279 &gEfiDevicePathProtocolGuid
,
280 This
->DriverBindingHandle
,
285 &gEfiPciIoProtocolGuid
,
286 This
->DriverBindingHandle
,
292 // The IsaBus driver will use memory below 16M, which is not tested yet,
293 // so call CompatibleRangeTest to test them. Since memory below 1M should
294 // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M
297 Status
= gBS
->LocateProtocol (
298 &gEfiGenericMemTestProtocolGuid
,
300 (VOID
**) &GenMemoryTest
303 if (!EFI_ERROR (Status
)) {
304 Status
= GenMemoryTest
->CompatibleRangeTest (
311 // Report Status Code here since we will initialize the host controller
313 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
315 (EFI_IO_BUS_LPC
| EFI_IOB_PC_INIT
),
320 // first init ISA interface
322 IsaAcpi
->InterfaceInit (IsaAcpi
);
325 // Report Status Code here since we will enable the host controller
327 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
329 (EFI_IO_BUS_LPC
| EFI_IOB_PC_ENABLE
),
334 // Create each ISA device handle in this ISA bus
338 Status
= IsaAcpi
->DeviceEnumerate (IsaAcpi
, &IsaDevice
);
339 if (EFI_ERROR (Status
)) {
343 // Get current resource of this ISA device
346 Status
= IsaAcpi
->GetCurResource (IsaAcpi
, IsaDevice
, &ResourceList
);
347 if (EFI_ERROR (Status
)) {
352 // Create handle for this ISA device
354 Status
= IsaCreateDevice (
361 //&AllocFailExtendedData.DevicePath
364 if (EFI_ERROR (Status
)) {
368 // Initialize ISA device
370 IsaAcpi
->InitDevice (IsaAcpi
, IsaDevice
);
373 // Set resources for this ISA device
375 Status
= IsaAcpi
->SetResource (IsaAcpi
, IsaDevice
, ResourceList
);
378 // Report Status Code here when failed to resource conflicts
380 if (EFI_ERROR (Status
) && (Status
!= EFI_UNSUPPORTED
)) {
382 // It's hard to tell which resource conflicts
384 AllocFailExtendedData
.Bar
= 0;
385 AllocFailExtendedData
.ReqRes
= NULL
;
386 AllocFailExtendedData
.AllocRes
= NULL
;
387 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
389 (EFI_IO_BUS_LPC
| EFI_IOB_EC_RESOURCE_CONFLICT
),
395 // Set power for this ISA device
397 IsaAcpi
->SetPower (IsaAcpi
, IsaDevice
, TRUE
);
400 // Enable this ISA device
402 IsaAcpi
->EnableDevice (IsaAcpi
, IsaDevice
, TRUE
);
411 IsaBusControllerDriverStop (
412 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
413 IN EFI_HANDLE Controller
,
414 IN UINTN NumberOfChildren
,
415 IN EFI_HANDLE
* ChildHandleBuffer OPTIONAL
421 This function tells the ISA Bus Driver to stop managing a PCI to ISA
426 This - The EFI_DRIVER_BINDING_PROTOCOL instance.
427 Controller - A handle to the device being stopped.
428 NumberOfChindren - The number of child device handles in ChildHandleBuffer.
429 ChildHandleBuffer - An array of child handles to be freed.
434 EFI_SUCCESS - The device was stopped.
435 EFI_DEVICE_ERROR - The device could not be stopped due to a device error.
436 EFI_NOT_STARTED - The device has not been started.
437 EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
438 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
445 BOOLEAN AllChildrenStopped
;
446 ISA_IO_DEVICE
*IsaIoDevice
;
447 EFI_ISA_IO_PROTOCOL
*IsaIo
;
449 if (NumberOfChildren
== 0) {
451 // Close the bus driver
453 Status
= gBS
->CloseProtocol (
455 &gEfiPciIoProtocolGuid
,
456 This
->DriverBindingHandle
,
459 if (EFI_ERROR (Status
)) {
463 Status
= gBS
->CloseProtocol (
465 &gEfiDevicePathProtocolGuid
,
466 This
->DriverBindingHandle
,
469 if (EFI_ERROR (Status
)) {
473 Status
= gBS
->CloseProtocol (
475 &gEfiIsaAcpiProtocolGuid
,
476 This
->DriverBindingHandle
,
479 if (EFI_ERROR (Status
)) {
486 // Complete all outstanding transactions to Controller.
487 // Don't allow any new transaction to Controller to be started.
490 // Stop all the children
491 // Find all the ISA devices that were discovered on this PCI to ISA Bridge
492 // with the Start() function.
494 AllChildrenStopped
= TRUE
;
496 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
498 Status
= gBS
->OpenProtocol (
499 ChildHandleBuffer
[Index
],
500 &gEfiIsaIoProtocolGuid
,
502 This
->DriverBindingHandle
,
504 EFI_OPEN_PROTOCOL_GET_PROTOCOL
506 if (!EFI_ERROR (Status
)) {
508 IsaIoDevice
= ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo
);
510 Status
= gBS
->UninstallMultipleProtocolInterfaces (
511 ChildHandleBuffer
[Index
],
512 &gEfiDevicePathProtocolGuid
,
513 IsaIoDevice
->DevicePath
,
514 &gEfiIsaIoProtocolGuid
,
519 if (!EFI_ERROR (Status
)) {
521 // Close the child handle
523 Status
= gBS
->CloseProtocol (
525 &gEfiPciIoProtocolGuid
,
526 This
->DriverBindingHandle
,
527 ChildHandleBuffer
[Index
]
530 gBS
->FreePool (IsaIoDevice
->DevicePath
);
531 gBS
->FreePool (IsaIoDevice
);
535 if (EFI_ERROR (Status
)) {
536 AllChildrenStopped
= FALSE
;
540 if (!AllChildrenStopped
) {
541 return EFI_DEVICE_ERROR
;
551 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
552 IN EFI_HANDLE Controller
,
553 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
554 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
555 IN EFI_ISA_ACPI_RESOURCE_LIST
*IsaDeviceResourceList
,
556 OUT EFI_DEVICE_PATH_PROTOCOL
**ChildDevicePath
562 Create ISA device found by IsaPnpProtocol
566 This - The EFI_DRIVER_BINDING_PROTOCOL instance.
567 Controller - The handle of ISA bus controller(PCI to ISA bridge)
568 PciIo - The Pointer to the PCI protocol
569 ParentDevicePath - Device path of the ISA bus controller
570 IsaDeviceResourceList - The resource list of the ISA device
571 ChildDevicePath - The pointer to the child device.
575 EFI_SUCCESS - Create the child device.
576 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
578 EFI_DEVICE_ERROR - Can not create child device.
583 ISA_IO_DEVICE
*IsaIoDevice
;
587 // Initialize the PCI_IO_DEVICE structure
589 IsaIoDevice
= AllocateZeroPool (sizeof (ISA_IO_DEVICE
));
590 if (IsaIoDevice
== NULL
) {
591 return EFI_OUT_OF_RESOURCES
;
594 IsaIoDevice
->Signature
= ISA_IO_DEVICE_SIGNATURE
;
595 IsaIoDevice
->Handle
= NULL
;
596 IsaIoDevice
->PciIo
= PciIo
;
599 // Initialize the ISA I/O instance structure
601 Status
= InitializeIsaIoInstance (IsaIoDevice
, IsaDeviceResourceList
);
602 if (EFI_ERROR (Status
)) {
603 gBS
->FreePool (IsaIoDevice
);
607 // Build the child device path
609 Node
.DevPath
.Type
= ACPI_DEVICE_PATH
;
610 Node
.DevPath
.SubType
= ACPI_DP
;
611 SetDevicePathNodeLength (&Node
.DevPath
, sizeof (ACPI_HID_DEVICE_PATH
));
612 Node
.Acpi
.HID
= IsaDeviceResourceList
->Device
.HID
;
613 Node
.Acpi
.UID
= IsaDeviceResourceList
->Device
.UID
;
615 IsaIoDevice
->DevicePath
= AppendDevicePathNode (
620 if (IsaIoDevice
->DevicePath
== NULL
) {
621 Status
= EFI_DEVICE_ERROR
;
625 *ChildDevicePath
= IsaIoDevice
->DevicePath
;
628 // Create a child handle and attach the DevicePath,
629 // PCI I/O, and Controller State
631 Status
= gBS
->InstallMultipleProtocolInterfaces (
632 &IsaIoDevice
->Handle
,
633 &gEfiDevicePathProtocolGuid
,
634 IsaIoDevice
->DevicePath
,
635 &gEfiIsaIoProtocolGuid
,
639 if (EFI_ERROR (Status
)) {
643 Status
= gBS
->OpenProtocol (
645 &gEfiPciIoProtocolGuid
,
647 This
->DriverBindingHandle
,
649 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
651 if (EFI_ERROR (Status
)) {
652 gBS
->UninstallMultipleProtocolInterfaces (
654 &gEfiDevicePathProtocolGuid
,
655 IsaIoDevice
->DevicePath
,
656 &gEfiIsaIoProtocolGuid
,
664 if (EFI_ERROR (Status
)) {
665 if (IsaIoDevice
->DevicePath
!= NULL
) {
666 gBS
->FreePool (IsaIoDevice
->DevicePath
);
669 gBS
->FreePool (IsaIoDevice
);