]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
Remove unnecessary use of gEfiStatusCodeSpecificDataGuid
[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
c3902377 211 EFI_DEVICE_PATH_PROTOCOL *DevicePathData;\r
212\r
c3902377 213 //\r
214 // Open Device Path Protocol\r
215 //\r
216 Status = gBS->OpenProtocol (\r
217 Controller,\r
218 &gEfiDevicePathProtocolGuid,\r
219 (VOID **) &ParentDevicePath,\r
220 This->DriverBindingHandle,\r
221 Controller,\r
222 EFI_OPEN_PROTOCOL_BY_DRIVER\r
223 );\r
224 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
225 return Status;\r
226 }\r
227 //\r
228 // Open Pci IO Protocol\r
229 //\r
230 Status = gBS->OpenProtocol (\r
231 Controller,\r
232 &gEfiPciIoProtocolGuid,\r
233 (VOID **) &PciIo,\r
234 This->DriverBindingHandle,\r
235 Controller,\r
236 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
237 );\r
238 if (EFI_ERROR (Status)) {\r
239 //\r
240 // Close opened protocol\r
241 //\r
242 gBS->CloseProtocol (\r
243 Controller,\r
244 &gEfiDevicePathProtocolGuid,\r
245 This->DriverBindingHandle,\r
246 Controller\r
247 );\r
248 return Status;\r
249 }\r
250 //\r
251 // Open ISA Acpi Protocol\r
252 //\r
253 Status = gBS->OpenProtocol (\r
254 Controller,\r
255 &gEfiIsaAcpiProtocolGuid,\r
256 (VOID **) &IsaAcpi,\r
257 This->DriverBindingHandle,\r
258 Controller,\r
259 EFI_OPEN_PROTOCOL_BY_DRIVER\r
260 );\r
261 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
262 //\r
263 // Close opened protocol\r
264 //\r
265 gBS->CloseProtocol (\r
266 Controller,\r
267 &gEfiDevicePathProtocolGuid,\r
268 This->DriverBindingHandle,\r
269 Controller\r
270 );\r
271 gBS->CloseProtocol (\r
272 Controller,\r
273 &gEfiPciIoProtocolGuid,\r
274 This->DriverBindingHandle,\r
275 Controller\r
276 );\r
277 return Status;\r
278 }\r
279 //\r
280 // The IsaBus driver will use memory below 16M, which is not tested yet,\r
281 // so call CompatibleRangeTest to test them. Since memory below 1M should\r
282 // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M\r
283 // ~15M here\r
284 //\r
285 Status = gBS->LocateProtocol (\r
286 &gEfiGenericMemTestProtocolGuid,\r
287 NULL,\r
288 (VOID **) &GenMemoryTest\r
289 );\r
290\r
291 if (!EFI_ERROR (Status)) {\r
292 Status = GenMemoryTest->CompatibleRangeTest (\r
293 GenMemoryTest,\r
294 0x100000,\r
295 0xE00000\r
296 );\r
297 }\r
298 //\r
299 // Report Status Code here since we will initialize the host controller\r
300 //\r
301 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
302 EFI_PROGRESS_CODE,\r
303 (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),\r
304 ParentDevicePath\r
305 );\r
306\r
307 //\r
308 // first init ISA interface\r
309 //\r
310 IsaAcpi->InterfaceInit (IsaAcpi);\r
311\r
312 //\r
313 // Report Status Code here since we will enable the host controller\r
314 //\r
315 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
316 EFI_PROGRESS_CODE,\r
317 (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),\r
318 ParentDevicePath\r
319 );\r
320\r
321 //\r
322 // Create each ISA device handle in this ISA bus\r
323 //\r
324 IsaDevice = NULL;\r
325 do {\r
326 Status = IsaAcpi->DeviceEnumerate (IsaAcpi, &IsaDevice);\r
327 if (EFI_ERROR (Status)) {\r
328 break;\r
329 }\r
330 //\r
331 // Get current resource of this ISA device\r
332 //\r
333 ResourceList = NULL;\r
334 Status = IsaAcpi->GetCurResource (IsaAcpi, IsaDevice, &ResourceList);\r
335 if (EFI_ERROR (Status)) {\r
336 continue;\r
337 }\r
338\r
339 //\r
340 // Create handle for this ISA device\r
341 //\r
342 Status = IsaCreateDevice (\r
343 This,\r
344 Controller,\r
345 PciIo,\r
346 ParentDevicePath,\r
347 ResourceList,\r
348 &DevicePathData\r
c3902377 349 );\r
350\r
351 if (EFI_ERROR (Status)) {\r
352 continue;\r
353 }\r
354 //\r
355 // Initialize ISA device\r
356 //\r
357 IsaAcpi->InitDevice (IsaAcpi, IsaDevice);\r
358\r
359 //\r
360 // Set resources for this ISA device\r
361 //\r
362 Status = IsaAcpi->SetResource (IsaAcpi, IsaDevice, ResourceList);\r
363\r
364 //\r
365 // Report Status Code here when failed to resource conflicts\r
366 //\r
367 if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {\r
368 //\r
369 // It's hard to tell which resource conflicts\r
370 //\r
c3902377 371 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
372 EFI_ERROR_CODE,\r
373 (EFI_IO_BUS_LPC | EFI_IOB_EC_RESOURCE_CONFLICT),\r
374 DevicePathData\r
375 );\r
376\r
377 }\r
378 //\r
379 // Set power for this ISA device\r
380 //\r
381 IsaAcpi->SetPower (IsaAcpi, IsaDevice, TRUE);\r
382\r
383 //\r
384 // Enable this ISA device\r
385 //\r
386 IsaAcpi->EnableDevice (IsaAcpi, IsaDevice, TRUE);\r
387\r
388 } while (TRUE);\r
389\r
c3902377 390 return EFI_SUCCESS;\r
391}\r
392\r
393EFI_STATUS\r
394EFIAPI\r
395IsaBusControllerDriverStop (\r
396 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
397 IN EFI_HANDLE Controller,\r
398 IN UINTN NumberOfChildren,\r
399 IN EFI_HANDLE * ChildHandleBuffer OPTIONAL\r
400 )\r
bcd70414 401/**\r
c3902377 402\r
403 Routine Description:\r
404 \r
405 This function tells the ISA Bus Driver to stop managing a PCI to ISA \r
406 Bridge controller. \r
407 \r
408 Arguments:\r
409 \r
410 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
411 Controller - A handle to the device being stopped.\r
412 NumberOfChindren - The number of child device handles in ChildHandleBuffer.\r
413 ChildHandleBuffer - An array of child handles to be freed.\r
414\r
415 \r
416 Returns:\r
417 \r
418 EFI_SUCCESS - The device was stopped.\r
419 EFI_DEVICE_ERROR - The device could not be stopped due to a device error.\r
420 EFI_NOT_STARTED - The device has not been started.\r
421 EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
422 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
423 resources.\r
424\r
bcd70414 425**/\r
c3902377 426{\r
427 EFI_STATUS Status;\r
428 UINTN Index;\r
429 BOOLEAN AllChildrenStopped;\r
430 ISA_IO_DEVICE *IsaIoDevice;\r
431 EFI_ISA_IO_PROTOCOL *IsaIo;\r
432\r
433 if (NumberOfChildren == 0) {\r
434 //\r
435 // Close the bus driver\r
436 //\r
437 Status = gBS->CloseProtocol (\r
438 Controller,\r
439 &gEfiPciIoProtocolGuid,\r
440 This->DriverBindingHandle,\r
441 Controller\r
442 );\r
443 if (EFI_ERROR (Status)) {\r
444 return Status;\r
445 }\r
446\r
447 Status = gBS->CloseProtocol (\r
448 Controller,\r
449 &gEfiDevicePathProtocolGuid,\r
450 This->DriverBindingHandle,\r
451 Controller\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 return Status;\r
455 }\r
456\r
457 Status = gBS->CloseProtocol (\r
458 Controller,\r
459 &gEfiIsaAcpiProtocolGuid,\r
460 This->DriverBindingHandle,\r
461 Controller\r
462 );\r
463 if (EFI_ERROR (Status)) {\r
464 return Status;\r
465 }\r
466\r
467 return EFI_SUCCESS;\r
468 }\r
469 //\r
470 // Complete all outstanding transactions to Controller.\r
471 // Don't allow any new transaction to Controller to be started.\r
472 //\r
473 //\r
474 // Stop all the children\r
475 // Find all the ISA devices that were discovered on this PCI to ISA Bridge\r
476 // with the Start() function.\r
477 //\r
478 AllChildrenStopped = TRUE;\r
479\r
480 for (Index = 0; Index < NumberOfChildren; Index++) {\r
481\r
482 Status = gBS->OpenProtocol (\r
483 ChildHandleBuffer[Index],\r
484 &gEfiIsaIoProtocolGuid,\r
485 (VOID **) &IsaIo,\r
486 This->DriverBindingHandle,\r
487 Controller,\r
488 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
489 );\r
490 if (!EFI_ERROR (Status)) {\r
491\r
492 IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
493\r
494 Status = gBS->UninstallMultipleProtocolInterfaces (\r
495 ChildHandleBuffer[Index],\r
496 &gEfiDevicePathProtocolGuid,\r
497 IsaIoDevice->DevicePath,\r
498 &gEfiIsaIoProtocolGuid,\r
499 &IsaIoDevice->IsaIo,\r
500 NULL\r
501 );\r
502\r
503 if (!EFI_ERROR (Status)) {\r
504 //\r
505 // Close the child handle\r
506 //\r
507 Status = gBS->CloseProtocol (\r
508 Controller,\r
509 &gEfiPciIoProtocolGuid,\r
510 This->DriverBindingHandle,\r
511 ChildHandleBuffer[Index]\r
512 );\r
513\r
514 gBS->FreePool (IsaIoDevice->DevicePath);\r
515 gBS->FreePool (IsaIoDevice);\r
516 }\r
517 }\r
518\r
519 if (EFI_ERROR (Status)) {\r
520 AllChildrenStopped = FALSE;\r
521 }\r
522 }\r
523\r
524 if (!AllChildrenStopped) {\r
525 return EFI_DEVICE_ERROR;\r
526 }\r
527\r
528 return EFI_SUCCESS;\r
529}\r
530//\r
531// Internal Function\r
532//\r
533EFI_STATUS\r
534IsaCreateDevice (\r
535 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
536 IN EFI_HANDLE Controller,\r
537 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
538 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
539 IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList,\r
540 OUT EFI_DEVICE_PATH_PROTOCOL **ChildDevicePath\r
541 )\r
bcd70414 542/**\r
c3902377 543\r
544 Routine Description:\r
545 \r
546 Create ISA device found by IsaPnpProtocol \r
547\r
548 Arguments:\r
549 \r
550 This - The EFI_DRIVER_BINDING_PROTOCOL instance.\r
551 Controller - The handle of ISA bus controller(PCI to ISA bridge)\r
552 PciIo - The Pointer to the PCI protocol \r
553 ParentDevicePath - Device path of the ISA bus controller\r
554 IsaDeviceResourceList - The resource list of the ISA device\r
555 ChildDevicePath - The pointer to the child device.\r
556\r
557 Returns:\r
558 \r
559 EFI_SUCCESS - Create the child device.\r
560 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of \r
561 resources.\r
562 EFI_DEVICE_ERROR - Can not create child device.\r
563 \r
bcd70414 564**/\r
c3902377 565{\r
566 EFI_STATUS Status;\r
567 ISA_IO_DEVICE *IsaIoDevice;\r
568 EFI_DEV_PATH Node;\r
569\r
570 //\r
571 // Initialize the PCI_IO_DEVICE structure\r
572 //\r
573 IsaIoDevice = AllocateZeroPool (sizeof (ISA_IO_DEVICE));\r
574 if (IsaIoDevice == NULL) {\r
575 return EFI_OUT_OF_RESOURCES;\r
576 }\r
577\r
578 IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;\r
579 IsaIoDevice->Handle = NULL;\r
580 IsaIoDevice->PciIo = PciIo;\r
581\r
582 //\r
583 // Initialize the ISA I/O instance structure\r
584 //\r
585 Status = InitializeIsaIoInstance (IsaIoDevice, IsaDeviceResourceList);\r
586 if (EFI_ERROR (Status)) {\r
587 gBS->FreePool (IsaIoDevice);\r
588 return Status;\r
589 }\r
590 //\r
591 // Build the child device path\r
592 //\r
593 Node.DevPath.Type = ACPI_DEVICE_PATH;\r
594 Node.DevPath.SubType = ACPI_DP;\r
595 SetDevicePathNodeLength (&Node.DevPath, sizeof (ACPI_HID_DEVICE_PATH));\r
596 Node.Acpi.HID = IsaDeviceResourceList->Device.HID;\r
597 Node.Acpi.UID = IsaDeviceResourceList->Device.UID;\r
598\r
599 IsaIoDevice->DevicePath = AppendDevicePathNode (\r
600 ParentDevicePath,\r
601 &Node.DevPath\r
602 );\r
603\r
604 if (IsaIoDevice->DevicePath == NULL) {\r
605 Status = EFI_DEVICE_ERROR;\r
606 goto Done;\r
607 }\r
608\r
609 *ChildDevicePath = IsaIoDevice->DevicePath;\r
610\r
611 //\r
612 // Create a child handle and attach the DevicePath,\r
613 // PCI I/O, and Controller State\r
614 //\r
615 Status = gBS->InstallMultipleProtocolInterfaces (\r
616 &IsaIoDevice->Handle,\r
617 &gEfiDevicePathProtocolGuid,\r
618 IsaIoDevice->DevicePath,\r
619 &gEfiIsaIoProtocolGuid,\r
620 &IsaIoDevice->IsaIo,\r
621 NULL\r
622 );\r
623 if (EFI_ERROR (Status)) {\r
624 goto Done;\r
625 }\r
626\r
627 Status = gBS->OpenProtocol (\r
628 Controller,\r
629 &gEfiPciIoProtocolGuid,\r
630 (VOID **) &PciIo,\r
631 This->DriverBindingHandle,\r
632 IsaIoDevice->Handle,\r
633 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
634 );\r
635 if (EFI_ERROR (Status)) {\r
636 gBS->UninstallMultipleProtocolInterfaces (\r
637 IsaIoDevice->Handle,\r
638 &gEfiDevicePathProtocolGuid,\r
639 IsaIoDevice->DevicePath,\r
640 &gEfiIsaIoProtocolGuid,\r
641 &IsaIoDevice->IsaIo,\r
642 NULL\r
643 );\r
644 }\r
645\r
646Done:\r
647\r
648 if (EFI_ERROR (Status)) {\r
649 if (IsaIoDevice->DevicePath != NULL) {\r
650 gBS->FreePool (IsaIoDevice->DevicePath);\r
651 }\r
652\r
653 gBS->FreePool (IsaIoDevice);\r
654 }\r
655\r
656 return Status;\r
657}\r