]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
Coding style modification.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaBusDxe / IsaBus.c
CommitLineData
f8cd287b 1/**@file\r
c3902377 2\r
3 Discovers all the ISA Controllers and their resources by using the ISA PnP \r
4 Protocol, produces an instance of the ISA I/O Protocol for every ISA \r
5 Controller found, loads and initializes all ISA Device Drivers, matches ISA\r
6 Device Drivers with their respective ISA Controllers in a deterministic \r
7 manner, and informs a ISA Device Driver when it is to start managing an ISA\r
8 Controller. \r
f8cd287b 9 \r
10Copyright (c) 2006 - 2007, Intel Corporation.<BR>\r
11All rights reserved. This program and the accompanying materials\r
12are licensed and made available under the terms and conditions of the BSD License\r
13which accompanies this distribution. The full text of the license may be found at\r
14http://opensource.org/licenses/bsd-license.php\r
15\r
16THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
17WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
c3902377 18\r
f8cd287b 19**/\r
c3902377 20\r
c3902377 21\r
22#include "InternalIsaBus.h"\r
23\r
24//\r
25// ISA Bus Driver Global Variables\r
26//\r
27EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver = {\r
28 IsaBusControllerDriverSupported,\r
29 IsaBusControllerDriverStart,\r
30 IsaBusControllerDriverStop,\r
31 0xa,\r
32 NULL,\r
33 NULL\r
34};\r
35\r
c55fa8cc 36/**\r
37 The user Entry Point for module IsaBus. The user code starts with this function.\r
38\r
39 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
40 @param[in] SystemTable A pointer to the EFI System Table.\r
41 \r
42 @retval EFI_SUCCESS The entry point is executed successfully.\r
43 @retval other Some error occurs when executing this entry point.\r
44\r
45**/\r
46EFI_STATUS\r
47EFIAPI\r
48InitializeIsaBus(\r
49 IN EFI_HANDLE ImageHandle,\r
50 IN EFI_SYSTEM_TABLE *SystemTable\r
51 )\r
52{\r
53 EFI_STATUS Status;\r
54\r
55 //\r
56 // Install driver model protocol(s).\r
57 //\r
f3d08ccf 58 Status = EfiLibInstallDriverBindingComponentName2 (\r
c55fa8cc 59 ImageHandle,\r
60 SystemTable,\r
61 &gIsaBusControllerDriver,\r
62 ImageHandle,\r
63 &gIsaBusComponentName,\r
f3d08ccf 64 &gIsaBusComponentName2\r
c55fa8cc 65 );\r
66 ASSERT_EFI_ERROR (Status);\r
67\r
68\r
69 return Status;\r
70}\r
71\r
72\r
c3902377 73EFI_STATUS\r
74EFIAPI\r
75IsaBusControllerDriverSupported (\r
76 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
77 IN EFI_HANDLE Controller,\r
78 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
79 )\r
bcd70414 80/**\r
c3902377 81\r
82 Routine Description:\r
83 \r
84 This function checks to see if a controller can be managed by the ISA Bus \r
85 Driver. This is done by checking to see if the controller supports the \r
86 EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration \r
87 Header to see if the device is a PCI to ISA bridge. The class code of \r
88 PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h \r
89 \r
90 Arguments:\r
91 \r
92 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
93 Controller - The handle of the device to check.\r
94 RemainingDevicePath - A pointer to the remaining portion of a device path.\r
95\r
96 Returns:\r
97 \r
98 EFI_SUCCESS - The device is supported by this driver.\r
99 EFI_UNSUPPORTED - The device is not supported by this driver.\r
100\r
bcd70414 101**/\r
c3902377 102{\r
103 EFI_STATUS Status;\r
104 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
105\r
106 //\r
107 // If RemainingDevicePath is not NULL, it should verify that the first device\r
108 // path node in RemainingDevicePath is an ACPI Device path node\r
109 //\r
110 if (RemainingDevicePath != NULL) {\r
111 if (RemainingDevicePath->Type != ACPI_DEVICE_PATH) {\r
112 return EFI_UNSUPPORTED;\r
113 } else if (RemainingDevicePath->SubType == ACPI_DP) {\r
114 if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH)) {\r
115 return EFI_UNSUPPORTED;\r
116 }\r
117 } else if (RemainingDevicePath->SubType == ACPI_EXTENDED_DP) {\r
118 if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)) {\r
119 return EFI_UNSUPPORTED;\r
120 }\r
121 } else {\r
122 return EFI_UNSUPPORTED;\r
123 }\r
124 }\r
125 //\r
126 // Test the existence of DEVICE_PATH protocol\r
127 //\r
128 Status = gBS->OpenProtocol (\r
129 Controller,\r
130 &gEfiDevicePathProtocolGuid,\r
131 NULL,\r
132 This->DriverBindingHandle,\r
133 Controller,\r
134 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
135 );\r
136 if (EFI_ERROR (Status)) {\r
137 return Status;\r
138 }\r
139 //\r
140 // Get the Isa Acpi protocol\r
141 //\r
142 Status = gBS->OpenProtocol (\r
143 Controller,\r
144 &gEfiIsaAcpiProtocolGuid,\r
145 (VOID **) &IsaAcpi,\r
146 This->DriverBindingHandle,\r
147 Controller,\r
148 EFI_OPEN_PROTOCOL_BY_DRIVER\r
149 );\r
150 if (Status == EFI_ALREADY_STARTED) {\r
151 return EFI_SUCCESS;\r
152 }\r
153\r
154 if (EFI_ERROR (Status)) {\r
155 return Status;\r
156 }\r
157\r
158 gBS->CloseProtocol (\r
159 Controller,\r
160 &gEfiIsaAcpiProtocolGuid,\r
161 This->DriverBindingHandle,\r
162 Controller\r
163 );\r
164\r
165 return Status;\r
166}\r
167\r
168EFI_STATUS\r
169EFIAPI\r
170IsaBusControllerDriverStart (\r
171 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
172 IN EFI_HANDLE Controller,\r
173 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
174 )\r
bcd70414 175/**\r
c3902377 176\r
177 Routine Description:\r
178 \r
179 This function tells the ISA Bus Driver to start managing a PCI to ISA \r
180 Bridge controller. \r
181 \r
182 Arguments:\r
183 \r
184 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
185 Controller - A handle to the device being started. \r
186 RemainingDevicePath - A pointer to the remaining portion of a device path.\r
187\r
188 Returns:\r
189 \r
190 EFI_SUCCESS - The device was started.\r
191 EFI_UNSUPPORTED - The device is not supported.\r
192 EFI_DEVICE_ERROR - The device could not be started due to a device error.\r
193 EFI_ALREADY_STARTED - The device has already been started.\r
194 EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
195 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
196 resources.\r
197 \r
bcd70414 198**/\r
c3902377 199{\r
200 EFI_STATUS Status;\r
201 EFI_PCI_IO_PROTOCOL *PciIo;\r
202 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
203 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
204 EFI_ISA_ACPI_DEVICE_ID *IsaDevice;\r
205 EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;\r
206 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;\r
207\r
208 //\r
209 // Local variables declaration for StatusCode reporting\r
210 //\r
211 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;\r
212 EFI_DEVICE_PATH_PROTOCOL *DevicePathData;\r
213\r
c3902377 214 //\r
215 // Initialize status code structure\r
216 //\r
217 AllocFailExtendedData.DataHeader.HeaderSize = sizeof (EFI_STATUS_CODE_DATA);\r
218 AllocFailExtendedData.DataHeader.Size = sizeof (EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA) - sizeof (EFI_STATUS_CODE_DATA);\r
219 CopyMem (\r
220 &AllocFailExtendedData.DataHeader.Type,\r
221 &gEfiStatusCodeSpecificDataGuid,\r
222 sizeof (EFI_GUID)\r
223 );\r
224\r
225 //\r
226 // Open Device Path Protocol\r
227 //\r
228 Status = gBS->OpenProtocol (\r
229 Controller,\r
230 &gEfiDevicePathProtocolGuid,\r
231 (VOID **) &ParentDevicePath,\r
232 This->DriverBindingHandle,\r
233 Controller,\r
234 EFI_OPEN_PROTOCOL_BY_DRIVER\r
235 );\r
236 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
237 return Status;\r
238 }\r
239 //\r
240 // Open Pci IO Protocol\r
241 //\r
242 Status = gBS->OpenProtocol (\r
243 Controller,\r
244 &gEfiPciIoProtocolGuid,\r
245 (VOID **) &PciIo,\r
246 This->DriverBindingHandle,\r
247 Controller,\r
248 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
249 );\r
250 if (EFI_ERROR (Status)) {\r
251 //\r
252 // Close opened protocol\r
253 //\r
254 gBS->CloseProtocol (\r
255 Controller,\r
256 &gEfiDevicePathProtocolGuid,\r
257 This->DriverBindingHandle,\r
258 Controller\r
259 );\r
260 return Status;\r
261 }\r
262 //\r
263 // Open ISA Acpi Protocol\r
264 //\r
265 Status = gBS->OpenProtocol (\r
266 Controller,\r
267 &gEfiIsaAcpiProtocolGuid,\r
268 (VOID **) &IsaAcpi,\r
269 This->DriverBindingHandle,\r
270 Controller,\r
271 EFI_OPEN_PROTOCOL_BY_DRIVER\r
272 );\r
273 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
274 //\r
275 // Close opened protocol\r
276 //\r
277 gBS->CloseProtocol (\r
278 Controller,\r
279 &gEfiDevicePathProtocolGuid,\r
280 This->DriverBindingHandle,\r
281 Controller\r
282 );\r
283 gBS->CloseProtocol (\r
284 Controller,\r
285 &gEfiPciIoProtocolGuid,\r
286 This->DriverBindingHandle,\r
287 Controller\r
288 );\r
289 return Status;\r
290 }\r
291 //\r
292 // The IsaBus driver will use memory below 16M, which is not tested yet,\r
293 // so call CompatibleRangeTest to test them. Since memory below 1M should\r
294 // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M\r
295 // ~15M here\r
296 //\r
297 Status = gBS->LocateProtocol (\r
298 &gEfiGenericMemTestProtocolGuid,\r
299 NULL,\r
300 (VOID **) &GenMemoryTest\r
301 );\r
302\r
303 if (!EFI_ERROR (Status)) {\r
304 Status = GenMemoryTest->CompatibleRangeTest (\r
305 GenMemoryTest,\r
306 0x100000,\r
307 0xE00000\r
308 );\r
309 }\r
310 //\r
311 // Report Status Code here since we will initialize the host controller\r
312 //\r
313 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
314 EFI_PROGRESS_CODE,\r
315 (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),\r
316 ParentDevicePath\r
317 );\r
318\r
319 //\r
320 // first init ISA interface\r
321 //\r
322 IsaAcpi->InterfaceInit (IsaAcpi);\r
323\r
324 //\r
325 // Report Status Code here since we will enable the host controller\r
326 //\r
327 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
328 EFI_PROGRESS_CODE,\r
329 (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),\r
330 ParentDevicePath\r
331 );\r
332\r
333 //\r
334 // Create each ISA device handle in this ISA bus\r
335 //\r
336 IsaDevice = NULL;\r
337 do {\r
338 Status = IsaAcpi->DeviceEnumerate (IsaAcpi, &IsaDevice);\r
339 if (EFI_ERROR (Status)) {\r
340 break;\r
341 }\r
342 //\r
343 // Get current resource of this ISA device\r
344 //\r
345 ResourceList = NULL;\r
346 Status = IsaAcpi->GetCurResource (IsaAcpi, IsaDevice, &ResourceList);\r
347 if (EFI_ERROR (Status)) {\r
348 continue;\r
349 }\r
350\r
351 //\r
352 // Create handle for this ISA device\r
353 //\r
354 Status = IsaCreateDevice (\r
355 This,\r
356 Controller,\r
357 PciIo,\r
358 ParentDevicePath,\r
359 ResourceList,\r
360 &DevicePathData\r
361 //&AllocFailExtendedData.DevicePath\r
362 );\r
363\r
364 if (EFI_ERROR (Status)) {\r
365 continue;\r
366 }\r
367 //\r
368 // Initialize ISA device\r
369 //\r
370 IsaAcpi->InitDevice (IsaAcpi, IsaDevice);\r
371\r
372 //\r
373 // Set resources for this ISA device\r
374 //\r
375 Status = IsaAcpi->SetResource (IsaAcpi, IsaDevice, ResourceList);\r
376\r
377 //\r
378 // Report Status Code here when failed to resource conflicts\r
379 //\r
380 if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {\r
381 //\r
382 // It's hard to tell which resource conflicts\r
383 //\r
384 AllocFailExtendedData.Bar = 0;\r
385 AllocFailExtendedData.ReqRes = NULL;\r
386 AllocFailExtendedData.AllocRes = NULL;\r
387 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
388 EFI_ERROR_CODE,\r
389 (EFI_IO_BUS_LPC | EFI_IOB_EC_RESOURCE_CONFLICT),\r
390 DevicePathData\r
391 );\r
392\r
393 }\r
394 //\r
395 // Set power for this ISA device\r
396 //\r
397 IsaAcpi->SetPower (IsaAcpi, IsaDevice, TRUE);\r
398\r
399 //\r
400 // Enable this ISA device\r
401 //\r
402 IsaAcpi->EnableDevice (IsaAcpi, IsaDevice, TRUE);\r
403\r
404 } while (TRUE);\r
405\r
c3902377 406 return EFI_SUCCESS;\r
407}\r
408\r
409EFI_STATUS\r
410EFIAPI\r
411IsaBusControllerDriverStop (\r
412 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
413 IN EFI_HANDLE Controller,\r
414 IN UINTN NumberOfChildren,\r
415 IN EFI_HANDLE * ChildHandleBuffer OPTIONAL\r
416 )\r
bcd70414 417/**\r
c3902377 418\r
419 Routine Description:\r
420 \r
421 This function tells the ISA Bus Driver to stop managing a PCI to ISA \r
422 Bridge controller. \r
423 \r
424 Arguments:\r
425 \r
426 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
427 Controller - A handle to the device being stopped.\r
428 NumberOfChindren - The number of child device handles in ChildHandleBuffer.\r
429 ChildHandleBuffer - An array of child handles to be freed.\r
430\r
431 \r
432 Returns:\r
433 \r
434 EFI_SUCCESS - The device was stopped.\r
435 EFI_DEVICE_ERROR - The device could not be stopped due to a device error.\r
436 EFI_NOT_STARTED - The device has not been started.\r
437 EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
438 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
439 resources.\r
440\r
bcd70414 441**/\r
c3902377 442{\r
443 EFI_STATUS Status;\r
444 UINTN Index;\r
445 BOOLEAN AllChildrenStopped;\r
446 ISA_IO_DEVICE *IsaIoDevice;\r
447 EFI_ISA_IO_PROTOCOL *IsaIo;\r
448\r
449 if (NumberOfChildren == 0) {\r
450 //\r
451 // Close the bus driver\r
452 //\r
453 Status = gBS->CloseProtocol (\r
454 Controller,\r
455 &gEfiPciIoProtocolGuid,\r
456 This->DriverBindingHandle,\r
457 Controller\r
458 );\r
459 if (EFI_ERROR (Status)) {\r
460 return Status;\r
461 }\r
462\r
463 Status = gBS->CloseProtocol (\r
464 Controller,\r
465 &gEfiDevicePathProtocolGuid,\r
466 This->DriverBindingHandle,\r
467 Controller\r
468 );\r
469 if (EFI_ERROR (Status)) {\r
470 return Status;\r
471 }\r
472\r
473 Status = gBS->CloseProtocol (\r
474 Controller,\r
475 &gEfiIsaAcpiProtocolGuid,\r
476 This->DriverBindingHandle,\r
477 Controller\r
478 );\r
479 if (EFI_ERROR (Status)) {\r
480 return Status;\r
481 }\r
482\r
483 return EFI_SUCCESS;\r
484 }\r
485 //\r
486 // Complete all outstanding transactions to Controller.\r
487 // Don't allow any new transaction to Controller to be started.\r
488 //\r
489 //\r
490 // Stop all the children\r
491 // Find all the ISA devices that were discovered on this PCI to ISA Bridge\r
492 // with the Start() function.\r
493 //\r
494 AllChildrenStopped = TRUE;\r
495\r
496 for (Index = 0; Index < NumberOfChildren; Index++) {\r
497\r
498 Status = gBS->OpenProtocol (\r
499 ChildHandleBuffer[Index],\r
500 &gEfiIsaIoProtocolGuid,\r
501 (VOID **) &IsaIo,\r
502 This->DriverBindingHandle,\r
503 Controller,\r
504 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
505 );\r
506 if (!EFI_ERROR (Status)) {\r
507\r
508 IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
509\r
510 Status = gBS->UninstallMultipleProtocolInterfaces (\r
511 ChildHandleBuffer[Index],\r
512 &gEfiDevicePathProtocolGuid,\r
513 IsaIoDevice->DevicePath,\r
514 &gEfiIsaIoProtocolGuid,\r
515 &IsaIoDevice->IsaIo,\r
516 NULL\r
517 );\r
518\r
519 if (!EFI_ERROR (Status)) {\r
520 //\r
521 // Close the child handle\r
522 //\r
523 Status = gBS->CloseProtocol (\r
524 Controller,\r
525 &gEfiPciIoProtocolGuid,\r
526 This->DriverBindingHandle,\r
527 ChildHandleBuffer[Index]\r
528 );\r
529\r
530 gBS->FreePool (IsaIoDevice->DevicePath);\r
531 gBS->FreePool (IsaIoDevice);\r
532 }\r
533 }\r
534\r
535 if (EFI_ERROR (Status)) {\r
536 AllChildrenStopped = FALSE;\r
537 }\r
538 }\r
539\r
540 if (!AllChildrenStopped) {\r
541 return EFI_DEVICE_ERROR;\r
542 }\r
543\r
544 return EFI_SUCCESS;\r
545}\r
546//\r
547// Internal Function\r
548//\r
549EFI_STATUS\r
550IsaCreateDevice (\r
551 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
552 IN EFI_HANDLE Controller,\r
553 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
554 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
555 IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList,\r
556 OUT EFI_DEVICE_PATH_PROTOCOL **ChildDevicePath\r
557 )\r
bcd70414 558/**\r
c3902377 559\r
560 Routine Description:\r
561 \r
562 Create ISA device found by IsaPnpProtocol \r
563\r
564 Arguments:\r
565 \r
566 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
567 Controller - The handle of ISA bus controller(PCI to ISA bridge)\r
568 PciIo - The Pointer to the PCI protocol \r
569 ParentDevicePath - Device path of the ISA bus controller\r
570 IsaDeviceResourceList - The resource list of the ISA device\r
571 ChildDevicePath - The pointer to the child device.\r
572\r
573 Returns:\r
574 \r
575 EFI_SUCCESS - Create the child device.\r
576 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
577 resources.\r
578 EFI_DEVICE_ERROR - Can not create child device.\r
579 \r
bcd70414 580**/\r
c3902377 581{\r
582 EFI_STATUS Status;\r
583 ISA_IO_DEVICE *IsaIoDevice;\r
584 EFI_DEV_PATH Node;\r
585\r
586 //\r
587 // Initialize the PCI_IO_DEVICE structure\r
588 //\r
589 IsaIoDevice = AllocateZeroPool (sizeof (ISA_IO_DEVICE));\r
590 if (IsaIoDevice == NULL) {\r
591 return EFI_OUT_OF_RESOURCES;\r
592 }\r
593\r
594 IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;\r
595 IsaIoDevice->Handle = NULL;\r
596 IsaIoDevice->PciIo = PciIo;\r
597\r
598 //\r
599 // Initialize the ISA I/O instance structure\r
600 //\r
601 Status = InitializeIsaIoInstance (IsaIoDevice, IsaDeviceResourceList);\r
602 if (EFI_ERROR (Status)) {\r
603 gBS->FreePool (IsaIoDevice);\r
604 return Status;\r
605 }\r
606 //\r
607 // Build the child device path\r
608 //\r
609 Node.DevPath.Type = ACPI_DEVICE_PATH;\r
610 Node.DevPath.SubType = ACPI_DP;\r
611 SetDevicePathNodeLength (&Node.DevPath, sizeof (ACPI_HID_DEVICE_PATH));\r
612 Node.Acpi.HID = IsaDeviceResourceList->Device.HID;\r
613 Node.Acpi.UID = IsaDeviceResourceList->Device.UID;\r
614\r
615 IsaIoDevice->DevicePath = AppendDevicePathNode (\r
616 ParentDevicePath,\r
617 &Node.DevPath\r
618 );\r
619\r
620 if (IsaIoDevice->DevicePath == NULL) {\r
621 Status = EFI_DEVICE_ERROR;\r
622 goto Done;\r
623 }\r
624\r
625 *ChildDevicePath = IsaIoDevice->DevicePath;\r
626\r
627 //\r
628 // Create a child handle and attach the DevicePath,\r
629 // PCI I/O, and Controller State\r
630 //\r
631 Status = gBS->InstallMultipleProtocolInterfaces (\r
632 &IsaIoDevice->Handle,\r
633 &gEfiDevicePathProtocolGuid,\r
634 IsaIoDevice->DevicePath,\r
635 &gEfiIsaIoProtocolGuid,\r
636 &IsaIoDevice->IsaIo,\r
637 NULL\r
638 );\r
639 if (EFI_ERROR (Status)) {\r
640 goto Done;\r
641 }\r
642\r
643 Status = gBS->OpenProtocol (\r
644 Controller,\r
645 &gEfiPciIoProtocolGuid,\r
646 (VOID **) &PciIo,\r
647 This->DriverBindingHandle,\r
648 IsaIoDevice->Handle,\r
649 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
650 );\r
651 if (EFI_ERROR (Status)) {\r
652 gBS->UninstallMultipleProtocolInterfaces (\r
653 IsaIoDevice->Handle,\r
654 &gEfiDevicePathProtocolGuid,\r
655 IsaIoDevice->DevicePath,\r
656 &gEfiIsaIoProtocolGuid,\r
657 &IsaIoDevice->IsaIo,\r
658 NULL\r
659 );\r
660 }\r
661\r
662Done:\r
663\r
664 if (EFI_ERROR (Status)) {\r
665 if (IsaIoDevice->DevicePath != NULL) {\r
666 gBS->FreePool (IsaIoDevice->DevicePath);\r
667 }\r
668\r
669 gBS->FreePool (IsaIoDevice);\r
670 }\r
671\r
672 return Status;\r
673}\r