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