]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/DeviceIoToPciRootBridgeIoThunk/DeviceIoToPciRootBridgeIoThunk.c
clean up the un-suitable ';' location when declaring the functions. The regular is...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / DeviceIoToPciRootBridgeIoThunk / DeviceIoToPciRootBridgeIoThunk.c
CommitLineData
fd4ae733 1/** @file\r
6ea838c3 2Module produces Device I/O on top of PCI Root Bridge I/O for Segment 0 only.\r
3This is a valid assumption because many of the EFI 1.02/EFI 1.10 systems that may have provided \r
4Device I/O were single segment platforms. The goal of the ECP is to provide compatibility with the \r
5drivers/apps that may have used Device I/O.\r
fd4ae733 6\r
7Device I/O is on list of deprecated protocols for UEFI 2.0 and later.\r
8This module module layers Device I/O on top of PCI Root Bridge I/O (Segment 0)\r
9 Use if:\r
10 There are no R8.x modules present that produces Device I/O\r
11 EFI drivers included that consume Device I/O\r
12 Platform required to support EFI drivers that consume Device I/O\r
13 Platform required to support EFI applications that consume Device I/O\r
14\r
15Copyright (c) 2008 Intel Corporation. <BR>\r
16All rights reserved. This program and the accompanying materials\r
17are licensed and made available under the terms and conditions of the BSD License\r
18which accompanies this distribution. The full text of the license may be found at\r
19http://opensource.org/licenses/bsd-license.php\r
20\r
21THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
22WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
23\r
24**/\r
25\r
26#include <PiDxe.h>\r
27#include <IndustryStandard/Pci22.h>\r
28#include <Protocol/DeviceIo.h>\r
29#include <Protocol/PciRootBridgeIo.h>\r
30#include <Library/BaseLib.h>\r
31#include <Library/BaseMemoryLib.h>\r
32#include <Library/DebugLib.h>\r
33#include <Library/UefiBootServicesTableLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/MemoryAllocationLib.h>\r
37#include <Library/DevicePathLib.h>\r
38\r
39\r
40/**\r
41 Perform reading memory mapped I/O space of device.\r
42\r
43 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
44 @param Width Width of I/O operations.\r
45 @param Address The base address of I/O operations.\r
46 @param Count The number of I/O operations to perform. Bytes\r
47 moves is Width size * Count, starting at Address.\r
48 @param Buffer The destination buffer to store results.\r
49\r
50 @retval EFI_SUCCESS The data was read from the device.\r
51 @retval EFI_INVALID_PARAMETER Width is invalid.\r
52 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
53 resources.\r
54\r
55**/\r
56EFI_STATUS\r
57EFIAPI\r
58DeviceIoMemRead (\r
59 IN EFI_DEVICE_IO_PROTOCOL *This,\r
60 IN EFI_IO_WIDTH Width,\r
61 IN UINT64 Address,\r
62 IN UINTN Count,\r
63 IN OUT VOID *Buffer\r
e00e1d46 64 );\r
fd4ae733 65\r
66\r
67/**\r
68 Perform writing memory mapped I/O space of device.\r
69\r
70 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
71 @param Width Width of I/O operations.\r
72 @param Address The base address of I/O operations.\r
73 @param Count The number of I/O operations to perform. Bytes\r
74 moves is Width size * Count, starting at Address.\r
75 @param Buffer The source buffer of data to be written.\r
76\r
77 @retval EFI_SUCCESS The data was written to the device.\r
78 @retval EFI_INVALID_PARAMETER Width is invalid.\r
79 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
80 resources.\r
81\r
82**/\r
83EFI_STATUS\r
84EFIAPI\r
85DeviceIoMemWrite (\r
86 IN EFI_DEVICE_IO_PROTOCOL *This,\r
87 IN EFI_IO_WIDTH Width,\r
88 IN UINT64 Address,\r
89 IN UINTN Count,\r
90 IN OUT VOID *Buffer\r
e00e1d46 91 );\r
fd4ae733 92\r
93/**\r
94 Perform reading I/O space of device.\r
95\r
96 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
97 @param Width Width of I/O operations.\r
98 @param Address The base address of I/O operations.\r
99 @param Count The number of I/O operations to perform. Bytes\r
100 moves is Width size * Count, starting at Address.\r
101 @param Buffer The destination buffer to store results.\r
102\r
103 @retval EFI_SUCCESS The data was read from the device.\r
104 @retval EFI_INVALID_PARAMETER Width is invalid.\r
105 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
106 resources.\r
107\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111DeviceIoIoRead (\r
112 IN EFI_DEVICE_IO_PROTOCOL *This,\r
113 IN EFI_IO_WIDTH Width,\r
114 IN UINT64 Address,\r
115 IN UINTN Count,\r
116 IN OUT VOID *Buffer\r
e00e1d46 117 );\r
fd4ae733 118\r
119/**\r
120 Perform writing I/O space of device.\r
121\r
122 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
123 @param Width Width of I/O operations.\r
124 @param Address The base address of I/O operations.\r
125 @param Count The number of I/O operations to perform. Bytes\r
126 moves is Width size * Count, starting at Address.\r
127 @param Buffer The source buffer of data to be written.\r
128\r
129 @retval EFI_SUCCESS The data was written to the device.\r
130 @retval EFI_INVALID_PARAMETER Width is invalid.\r
131 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
132 resources.\r
133\r
134**/\r
135EFI_STATUS\r
136EFIAPI\r
137DeviceIoIoWrite (\r
138 IN EFI_DEVICE_IO_PROTOCOL *This,\r
139 IN EFI_IO_WIDTH Width,\r
140 IN UINT64 Address,\r
141 IN UINTN Count,\r
142 IN OUT VOID *Buffer\r
e00e1d46 143 );\r
fd4ae733 144\r
145/**\r
146 Perform reading PCI configuration space of device\r
147\r
148 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
149 @param Width Width of I/O operations.\r
150 @param Address The base address of I/O operations.\r
151 @param Count The number of I/O operations to perform. Bytes\r
152 moves is Width size * Count, starting at Address.\r
153 @param Buffer The destination buffer to store results.\r
154\r
155 @retval EFI_SUCCESS The data was read from the device.\r
156 @retval EFI_INVALID_PARAMETER Width is invalid.\r
157 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
158 resources.\r
159\r
160**/\r
161EFI_STATUS\r
162EFIAPI\r
163DeviceIoPciRead (\r
164 IN EFI_DEVICE_IO_PROTOCOL *This,\r
165 IN EFI_IO_WIDTH Width,\r
166 IN UINT64 Address,\r
167 IN UINTN Count,\r
168 IN OUT VOID *Buffer\r
e00e1d46 169 );\r
fd4ae733 170\r
171/**\r
172 Perform writing PCI configuration space of device.\r
173\r
174 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
175 @param Width Width of I/O operations.\r
176 @param Address The base address of I/O operations.\r
177 @param Count The number of I/O operations to perform. Bytes\r
178 moves is Width size * Count, starting at Address.\r
179 @param Buffer The source buffer of data to be written.\r
180\r
181 @retval EFI_SUCCESS The data was written to the device.\r
182 @retval EFI_INVALID_PARAMETER Width is invalid.\r
183 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
184 resources.\r
185\r
186**/\r
187EFI_STATUS\r
188EFIAPI\r
189DeviceIoPciWrite (\r
190 IN EFI_DEVICE_IO_PROTOCOL *This,\r
191 IN EFI_IO_WIDTH Width,\r
192 IN UINT64 Address,\r
193 IN UINTN Count,\r
194 IN OUT VOID *Buffer\r
e00e1d46 195 );\r
fd4ae733 196\r
197/**\r
198 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.\r
199\r
200 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
201 @param Address The PCI configuration space address of the device\r
202 whose Device Path is going to be returned.\r
203 @param PciDevicePath A pointer to the pointer for the EFI Device Path\r
204 for PciAddress. Memory for the Device Path is\r
205 allocated from the pool.\r
206\r
207 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI\r
208 Device Path.\r
209 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device\r
210 Path.\r
211 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
212 of resources.\r
213\r
214**/\r
215EFI_STATUS\r
216EFIAPI\r
217DeviceIoPciDevicePath (\r
218 IN EFI_DEVICE_IO_PROTOCOL *This,\r
219 IN UINT64 Address,\r
220 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath\r
e00e1d46 221 );\r
fd4ae733 222\r
223/**\r
224 Provides the device-specific addresses needed to access system memory.\r
225\r
226 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
227 @param Operation Indicates if the bus master is going to read or\r
228 write to system memory.\r
229 @param HostAddress The system memory address to map to the device.\r
230 @param NumberOfBytes On input the number of bytes to map. On output the\r
231 number of bytes that were mapped.\r
232 @param DeviceAddress The resulting map address for the bus master\r
233 device to use to access the hosts HostAddress.\r
234 @param Mapping A resulting value to pass to Unmap().\r
235\r
236 @retval EFI_SUCCESS The range was mapped for the returned\r
237 NumberOfBytes.\r
238 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.\r
239 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common\r
240 buffer.\r
241 @retval EFI_DEVICE_ERROR The system hardware could not map the requested\r
242 address.\r
243 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
244 of resources.\r
245\r
246**/\r
247EFI_STATUS\r
248EFIAPI\r
249DeviceIoMap (\r
250 IN EFI_DEVICE_IO_PROTOCOL *This,\r
251 IN EFI_IO_OPERATION_TYPE Operation,\r
252 IN EFI_PHYSICAL_ADDRESS *HostAddress,\r
253 IN OUT UINTN *NumberOfBytes,\r
254 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
255 OUT VOID **Mapping\r
e00e1d46 256 );\r
fd4ae733 257\r
258/**\r
259 Completes the Map() operation and releases any corresponding resources.\r
260\r
261 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
262 @param Mapping The mapping value returned from Map().\r
263\r
264 @retval EFI_SUCCESS The range was unmapped.\r
265 @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
266 memory.\r
267\r
268**/\r
269EFI_STATUS\r
270EFIAPI\r
271DeviceIoUnmap (\r
272 IN EFI_DEVICE_IO_PROTOCOL *This,\r
273 IN VOID *Mapping\r
e00e1d46 274 );\r
fd4ae733 275\r
276/**\r
277 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.\r
278\r
279 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
280 @param Type The type allocation to perform.\r
281 @param MemoryType The type of memory to allocate,\r
282 EfiBootServicesData or EfiRuntimeServicesData.\r
283 @param Pages The number of pages to allocate.\r
284 @param PhysicalAddress A pointer to store the base address of the\r
285 allocated range.\r
286\r
287 @retval EFI_SUCCESS The requested memory pages were allocated.\r
288 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
289 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.\r
290 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on\r
291 this platform.\r
292\r
293**/\r
294EFI_STATUS\r
295EFIAPI\r
296DeviceIoAllocateBuffer (\r
297 IN EFI_DEVICE_IO_PROTOCOL *This,\r
298 IN EFI_ALLOCATE_TYPE Type,\r
299 IN EFI_MEMORY_TYPE MemoryType,\r
300 IN UINTN Pages,\r
301 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r
e00e1d46 302 );\r
fd4ae733 303\r
304/**\r
305 Flushes any posted write data to the device.\r
306\r
307 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
308\r
309 @retval EFI_SUCCESS The buffers were flushed.\r
310 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware\r
311 error.\r
312\r
313**/\r
314EFI_STATUS\r
315EFIAPI\r
316DeviceIoFlush (\r
317 IN EFI_DEVICE_IO_PROTOCOL *This\r
e00e1d46 318 );\r
fd4ae733 319\r
320/**\r
321 Frees pages that were allocated with AllocateBuffer().\r
322\r
323 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
324 @param Pages The number of pages to free.\r
325 @param HostAddress The base address of the range to free.\r
326\r
327 @retval EFI_SUCCESS The requested memory pages were freed.\r
328 @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
329 AllocateBuffer().\r
330 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is\r
331 invalid.\r
332\r
333**/\r
334EFI_STATUS\r
335EFIAPI\r
336DeviceIoFreeBuffer (\r
337 IN EFI_DEVICE_IO_PROTOCOL *This,\r
338 IN UINTN Pages,\r
339 IN EFI_PHYSICAL_ADDRESS HostAddress\r
e00e1d46 340 );\r
fd4ae733 341\r
342\r
343#define DEVICE_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('D', 'e', 'I', 'O')\r
344\r
345typedef struct {\r
346 UINTN Signature;\r
347 EFI_DEVICE_IO_PROTOCOL DeviceIo;\r
348 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
349 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
350 UINT16 PrimaryBus;\r
351 UINT16 SubordinateBus;\r
352} DEVICE_IO_PRIVATE_DATA;\r
353\r
354#define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)\r
355\r
356#define MAX_COMMON_BUFFER 0x00000000FFFFFFFF\r
357\r
358\r
359EFI_EVENT mPciRootBridgeIoRegistration;\r
360\r
361//\r
362// Device Io Volume Protocol template\r
363//\r
364DEVICE_IO_PRIVATE_DATA gDeviceIoPrivateDataTemplate = {\r
365 DEVICE_IO_PRIVATE_DATA_SIGNATURE,\r
366 {\r
367 {\r
368 DeviceIoMemRead,\r
369 DeviceIoMemWrite\r
370 },\r
371 {\r
372 DeviceIoIoRead,\r
373 DeviceIoIoWrite \r
374 },\r
375 {\r
376 DeviceIoPciRead,\r
377 DeviceIoPciWrite, \r
378 },\r
379 DeviceIoMap,\r
380 DeviceIoPciDevicePath,\r
381 DeviceIoUnmap,\r
382 DeviceIoAllocateBuffer,\r
383 DeviceIoFlush,\r
384 DeviceIoFreeBuffer\r
385 },\r
386 NULL, // PciRootBridgeIo\r
387 NULL, // DevicePath\r
388 0, // PrimaryBus\r
389 255 // SubordinateBus\r
390};\r
391\r
392VOID\r
393EFIAPI\r
394PciRootBridgeIoNotificationEvent (\r
395 IN EFI_EVENT Event,\r
396 IN VOID *Context\r
397 )\r
398{\r
399 EFI_STATUS Status;\r
400 UINTN BufferSize;\r
401 EFI_HANDLE Handle;\r
402 DEVICE_IO_PRIVATE_DATA *Private;\r
403 EFI_DEVICE_IO_PROTOCOL *DeviceIo;\r
404 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
405\r
406 while (TRUE) {\r
407 BufferSize = sizeof (Handle);\r
408 Status = gBS->LocateHandle (\r
409 ByRegisterNotify,\r
410 &gEfiPciRootBridgeIoProtocolGuid,\r
411 mPciRootBridgeIoRegistration,\r
412 &BufferSize,\r
413 &Handle\r
414 );\r
415 if (EFI_ERROR (Status)) {\r
416 //\r
417 // Exit Path of While Loop....\r
418 //\r
419 break;\r
420 }\r
421\r
422 //\r
423 // Skip this handle if the Device Io Protocol is already installed\r
424 //\r
425 Status = gBS->HandleProtocol (\r
426 Handle,\r
427 &gEfiDeviceIoProtocolGuid,\r
428 (VOID **)&DeviceIo\r
429 );\r
430 if (!EFI_ERROR (Status)) {\r
431 continue;\r
432 }\r
433\r
434 //\r
435 // Retrieve the Pci Root Bridge IO Protocol\r
436 //\r
437 Status = gBS->HandleProtocol (\r
438 Handle,\r
439 &gEfiPciRootBridgeIoProtocolGuid,\r
440 (VOID **)&PciRootBridgeIo\r
441 );\r
442 ASSERT_EFI_ERROR (Status);\r
443\r
444 //\r
6ea838c3 445 // We only install Device IO for PCI bus in Segment 0.\r
446 // See the file description at @file for details.\r
fd4ae733 447 //\r
448 if (PciRootBridgeIo->SegmentNumber != 0) {\r
449 continue;\r
450 }\r
451\r
452 //\r
453 // Allocate private data structure\r
454 //\r
455 Private = AllocateCopyPool (sizeof (DEVICE_IO_PRIVATE_DATA), &gDeviceIoPrivateDataTemplate);\r
456 if (Private == NULL) {\r
457 continue;\r
458 }\r
459\r
460 Status = gBS->HandleProtocol (\r
461 Handle,\r
462 &gEfiDevicePathProtocolGuid,\r
463 (VOID **) &Private->DevicePath\r
464 );\r
465\r
466 //\r
467 // Install Device Io onto same handle\r
468 //\r
469 Status = gBS->InstallMultipleProtocolInterfaces (\r
470 &Handle,\r
471 &gEfiDeviceIoProtocolGuid,\r
472 &Private->DeviceIo,\r
473 NULL\r
474 );\r
475 ASSERT_EFI_ERROR (Status);\r
476 }\r
477}\r
478\r
479/**\r
480 The user Entry Point for DXE driver. The user code starts with this function\r
481 as the real entry point for the image goes into a library that calls this \r
482 function.\r
483\r
484 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
485 @param[in] SystemTable A pointer to the EFI System Table.\r
486 \r
487 @retval EFI_SUCCESS The entry point is executed successfully.\r
488 @retval other Some error occurs when executing this entry point.\r
489\r
490**/\r
491EFI_STATUS\r
492EFIAPI\r
493InitializeDeviceIo (\r
494 IN EFI_HANDLE ImageHandle,\r
495 IN EFI_SYSTEM_TABLE *SystemTable\r
496 )\r
497{\r
498 EfiCreateProtocolNotifyEvent (\r
499 &gEfiPciRootBridgeIoProtocolGuid,\r
500 TPL_CALLBACK,\r
501 PciRootBridgeIoNotificationEvent,\r
502 NULL,\r
503 &mPciRootBridgeIoRegistration\r
504 );\r
505 return EFI_SUCCESS;\r
506}\r
507\r
508\r
509/**\r
510 Perform reading memory mapped I/O space of device.\r
511\r
512 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
513 @param Width Width of I/O operations.\r
514 @param Address The base address of I/O operations.\r
515 @param Count The number of I/O operations to perform. Bytes\r
516 moves is Width size * Count, starting at Address.\r
517 @param Buffer The destination buffer to store results.\r
518\r
519 @retval EFI_SUCCESS The data was read from the device.\r
520 @retval EFI_INVALID_PARAMETER Width is invalid.\r
521 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
522 resources.\r
523\r
524**/\r
525EFI_STATUS\r
526EFIAPI\r
527DeviceIoMemRead (\r
528 IN EFI_DEVICE_IO_PROTOCOL *This,\r
529 IN EFI_IO_WIDTH Width,\r
530 IN UINT64 Address,\r
531 IN UINTN Count,\r
532 IN OUT VOID *Buffer\r
533 )\r
534{\r
535 EFI_STATUS Status;\r
536 DEVICE_IO_PRIVATE_DATA *Private;\r
537\r
538 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
539\r
540 if (Width > MMIO_COPY_UINT64) {\r
541 return EFI_INVALID_PARAMETER;\r
542 }\r
543 if (Width >= MMIO_COPY_UINT8) {\r
544 Width = Width - MMIO_COPY_UINT8;\r
545 Status = Private->PciRootBridgeIo->CopyMem (\r
546 Private->PciRootBridgeIo,\r
547 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
548 (UINT64) (UINTN) Buffer,\r
549 Address,\r
550 Count\r
551 );\r
552 } else {\r
553 Status = Private->PciRootBridgeIo->Mem.Read (\r
554 Private->PciRootBridgeIo,\r
555 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
556 Address,\r
557 Count,\r
558 Buffer\r
559 );\r
560 }\r
561\r
562 return Status;\r
563}\r
564\r
565\r
566\r
567\r
568/**\r
569 Perform writing memory mapped I/O space of device.\r
570\r
571 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
572 @param Width Width of I/O operations.\r
573 @param Address The base address of I/O operations.\r
574 @param Count The number of I/O operations to perform. Bytes\r
575 moves is Width size * Count, starting at Address.\r
576 @param Buffer The source buffer of data to be written.\r
577\r
578 @retval EFI_SUCCESS The data was written to the device.\r
579 @retval EFI_INVALID_PARAMETER Width is invalid.\r
580 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
581 resources.\r
582\r
583**/\r
584EFI_STATUS\r
585EFIAPI\r
586DeviceIoMemWrite (\r
587 IN EFI_DEVICE_IO_PROTOCOL *This,\r
588 IN EFI_IO_WIDTH Width,\r
589 IN UINT64 Address,\r
590 IN UINTN Count,\r
591 IN OUT VOID *Buffer\r
592 )\r
593{\r
594 EFI_STATUS Status;\r
595 DEVICE_IO_PRIVATE_DATA *Private;\r
596\r
597 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
598\r
599 if (Width > MMIO_COPY_UINT64) {\r
600 return EFI_INVALID_PARAMETER;\r
601 }\r
602 if (Width >= MMIO_COPY_UINT8) {\r
603 Width = Width - MMIO_COPY_UINT8;\r
604 Status = Private->PciRootBridgeIo->CopyMem (\r
605 Private->PciRootBridgeIo,\r
606 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
607 Address,\r
608 (UINT64) (UINTN) Buffer,\r
609 Count\r
610 );\r
611 } else {\r
612 Status = Private->PciRootBridgeIo->Mem.Write (\r
613 Private->PciRootBridgeIo,\r
614 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
615 Address,\r
616 Count,\r
617 Buffer\r
618 );\r
619 }\r
620\r
621 return Status;\r
622}\r
623\r
624\r
625/**\r
626 Perform reading I/O space of device.\r
627\r
628 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
629 @param Width Width of I/O operations.\r
630 @param Address The base address of I/O operations.\r
631 @param Count The number of I/O operations to perform. Bytes\r
632 moves is Width size * Count, starting at Address.\r
633 @param Buffer The destination buffer to store results.\r
634\r
635 @retval EFI_SUCCESS The data was read from the device.\r
636 @retval EFI_INVALID_PARAMETER Width is invalid.\r
637 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
638 resources.\r
639\r
640**/\r
641EFI_STATUS\r
642EFIAPI\r
643DeviceIoIoRead (\r
644 IN EFI_DEVICE_IO_PROTOCOL *This,\r
645 IN EFI_IO_WIDTH Width,\r
646 IN UINT64 Address,\r
647 IN UINTN Count,\r
648 IN OUT VOID *Buffer\r
649 )\r
650{\r
651 EFI_STATUS Status;\r
652 DEVICE_IO_PRIVATE_DATA *Private;\r
653\r
654 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
655\r
656 if (Width >= MMIO_COPY_UINT8) {\r
657 return EFI_INVALID_PARAMETER;\r
658 }\r
659\r
660 Status = Private->PciRootBridgeIo->Io.Read (\r
661 Private->PciRootBridgeIo,\r
662 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
663 Address,\r
664 Count,\r
665 Buffer\r
666 );\r
667\r
668 return Status;\r
669}\r
670\r
671\r
672/**\r
673 Perform writing I/O space of device.\r
674\r
675 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
676 @param Width Width of I/O operations.\r
677 @param Address The base address of I/O operations.\r
678 @param Count The number of I/O operations to perform. Bytes\r
679 moves is Width size * Count, starting at Address.\r
680 @param Buffer The source buffer of data to be written.\r
681\r
682 @retval EFI_SUCCESS The data was written to the device.\r
683 @retval EFI_INVALID_PARAMETER Width is invalid.\r
684 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
685 resources.\r
686\r
687**/\r
688EFI_STATUS\r
689EFIAPI\r
690DeviceIoIoWrite (\r
691 IN EFI_DEVICE_IO_PROTOCOL *This,\r
692 IN EFI_IO_WIDTH Width,\r
693 IN UINT64 Address,\r
694 IN UINTN Count,\r
695 IN OUT VOID *Buffer\r
696 )\r
697{\r
698 EFI_STATUS Status;\r
699 DEVICE_IO_PRIVATE_DATA *Private;\r
700\r
701 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
702\r
703 if (Width >= MMIO_COPY_UINT8) {\r
704 return EFI_INVALID_PARAMETER;\r
705 }\r
706\r
707 Status = Private->PciRootBridgeIo->Io.Write (\r
708 Private->PciRootBridgeIo,\r
709 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
710 Address,\r
711 Count,\r
712 Buffer\r
713 );\r
714\r
715 return Status;\r
716}\r
717\r
718\r
719/**\r
720 Perform reading PCI configuration space of device\r
721\r
722 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
723 @param Width Width of I/O operations.\r
724 @param Address The base address of I/O operations.\r
725 @param Count The number of I/O operations to perform. Bytes\r
726 moves is Width size * Count, starting at Address.\r
727 @param Buffer The destination buffer to store results.\r
728\r
729 @retval EFI_SUCCESS The data was read from the device.\r
730 @retval EFI_INVALID_PARAMETER Width is invalid.\r
731 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
732 resources.\r
733\r
734**/\r
735EFI_STATUS\r
736EFIAPI\r
737DeviceIoPciRead (\r
738 IN EFI_DEVICE_IO_PROTOCOL *This,\r
739 IN EFI_IO_WIDTH Width,\r
740 IN UINT64 Address,\r
741 IN UINTN Count,\r
742 IN OUT VOID *Buffer\r
743 )\r
744{\r
745 EFI_STATUS Status;\r
746 DEVICE_IO_PRIVATE_DATA *Private;\r
747\r
748 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
749\r
750 if (Width < 0 || Width >= MMIO_COPY_UINT8) {\r
751 return EFI_INVALID_PARAMETER;\r
752 }\r
753\r
754 Status = Private->PciRootBridgeIo->Pci.Read (\r
755 Private->PciRootBridgeIo,\r
756 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
757 Address,\r
758 Count,\r
759 Buffer\r
760 );\r
761\r
762 return Status;\r
763}\r
764\r
765\r
766/**\r
767 Perform writing PCI configuration space of device.\r
768\r
769 @param This A pointer to EFI_DEVICE_IO protocol instance.\r
770 @param Width Width of I/O operations.\r
771 @param Address The base address of I/O operations.\r
772 @param Count The number of I/O operations to perform. Bytes\r
773 moves is Width size * Count, starting at Address.\r
774 @param Buffer The source buffer of data to be written.\r
775\r
776 @retval EFI_SUCCESS The data was written to the device.\r
777 @retval EFI_INVALID_PARAMETER Width is invalid.\r
778 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of\r
779 resources.\r
780\r
781**/\r
782EFI_STATUS\r
783EFIAPI\r
784DeviceIoPciWrite (\r
785 IN EFI_DEVICE_IO_PROTOCOL *This,\r
786 IN EFI_IO_WIDTH Width,\r
787 IN UINT64 Address,\r
788 IN UINTN Count,\r
789 IN OUT VOID *Buffer\r
790 )\r
791{\r
792 EFI_STATUS Status;\r
793 DEVICE_IO_PRIVATE_DATA *Private;\r
794\r
795 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
796\r
797 if (Width < 0 || Width >= MMIO_COPY_UINT8) {\r
798 return EFI_INVALID_PARAMETER;\r
799 }\r
800\r
801 Status = Private->PciRootBridgeIo->Pci.Write (\r
802 Private->PciRootBridgeIo,\r
803 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
804 Address,\r
805 Count,\r
806 Buffer\r
807 );\r
808\r
809 return Status;\r
810}\r
811\r
812\r
813/**\r
814 Append a PCI device path node to another device path.\r
815\r
816 @param Private A pointer to DEVICE_IO_PRIVATE_DATA instance.\r
817 @param Bus PCI bus number of the device.\r
818 @param Device PCI device number of the device.\r
819 @param Function PCI function number of the device.\r
820 @param DevicePath Original device path which will be appended a PCI\r
821 device path node.\r
822 @param BridgePrimaryBus Primary bus number of the bridge.\r
823 @param BridgeSubordinateBus Subordinate bus number of the bridge.\r
824\r
825 @return Pointer to the appended PCI device path.\r
826\r
827**/\r
828EFI_DEVICE_PATH_PROTOCOL *\r
829AppendPciDevicePath (\r
830 IN DEVICE_IO_PRIVATE_DATA *Private,\r
831 IN UINT8 Bus,\r
832 IN UINT8 Device,\r
833 IN UINT8 Function,\r
834 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
835 IN OUT UINT16 *BridgePrimaryBus,\r
836 IN OUT UINT16 *BridgeSubordinateBus\r
837 )\r
838{\r
839 UINT16 ThisBus;\r
840 UINT8 ThisDevice;\r
841 UINT8 ThisFunc;\r
842 UINT64 Address;\r
843 PCI_TYPE01 PciBridge;\r
844 PCI_TYPE01 *PciPtr;\r
845 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;\r
846 PCI_DEVICE_PATH PciNode;\r
847\r
848 PciPtr = &PciBridge;\r
849 for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {\r
850 for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {\r
851 for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {\r
852 Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);\r
853 ZeroMem (PciPtr, sizeof (PCI_TYPE01));\r
854 Private->DeviceIo.Pci.Read (\r
855 &Private->DeviceIo,\r
856 IO_UINT32,\r
857 Address,\r
858 1,\r
859 &(PciPtr->Hdr.VendorId)\r
860 );\r
861 if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {\r
862 break;\r
863 }\r
864 if (PciPtr->Hdr.VendorId == 0xffff) {\r
865 continue;\r
866 } else {\r
867 Private->DeviceIo.Pci.Read (\r
868 &Private->DeviceIo,\r
869 IO_UINT32,\r
870 Address,\r
871 sizeof (PCI_TYPE01) / sizeof (UINT32),\r
872 PciPtr\r
873 );\r
874 if (IS_PCI_BRIDGE (PciPtr)) {\r
875 if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {\r
876\r
877 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
878 PciNode.Header.SubType = HW_PCI_DP;\r
879 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
880\r
881 PciNode.Device = ThisDevice;\r
882 PciNode.Function = ThisFunc;\r
883 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
884\r
885 *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;\r
886 *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;\r
887 return ReturnDevicePath;\r
888 }\r
889 }\r
890 if (ThisFunc == 0 && !(PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)) {\r
891 //\r
892 // Skip sub functions, this is not a multi function device\r
893 //\r
894 ThisFunc = 8;\r
895 }\r
896 }\r
897 }\r
898 }\r
899 }\r
900\r
901 ZeroMem (&PciNode, sizeof (PciNode));\r
902 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
903 PciNode.Header.SubType = HW_PCI_DP;\r
904 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
905 PciNode.Device = Device;\r
906 PciNode.Function = Function;\r
907\r
908 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);\r
909\r
910 *BridgePrimaryBus = 0xffff;\r
911 *BridgeSubordinateBus = 0xffff;\r
912 return ReturnDevicePath;\r
913}\r
914\r
915\r
916/**\r
917 Provides an EFI Device Path for a PCI device with the given PCI configuration space address.\r
918\r
919 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
920 @param Address The PCI configuration space address of the device\r
921 whose Device Path is going to be returned.\r
922 @param PciDevicePath A pointer to the pointer for the EFI Device Path\r
923 for PciAddress. Memory for the Device Path is\r
924 allocated from the pool.\r
925\r
926 @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI\r
927 Device Path.\r
928 @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device\r
929 Path.\r
930 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
931 of resources.\r
932\r
933**/\r
934EFI_STATUS\r
935EFIAPI\r
936DeviceIoPciDevicePath (\r
937 IN EFI_DEVICE_IO_PROTOCOL *This,\r
938 IN UINT64 Address,\r
939 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath\r
940 )\r
941{\r
942 DEVICE_IO_PRIVATE_DATA *Private;\r
943 UINT16 PrimaryBus;\r
944 UINT16 SubordinateBus;\r
945 UINT8 Bus;\r
946 UINT8 Device;\r
947 UINT8 Func;\r
948\r
949 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
950\r
951 Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);\r
952 Device = (UINT8) (((UINT32) Address >> 16) & 0xff);\r
953 Func = (UINT8) (((UINT32) Address >> 8) & 0xff);\r
954\r
955 if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {\r
956 return EFI_UNSUPPORTED;\r
957 }\r
958\r
959 *PciDevicePath = Private->DevicePath;\r
960 PrimaryBus = Private->PrimaryBus;\r
961 SubordinateBus = Private->SubordinateBus;\r
962 do {\r
963 *PciDevicePath = AppendPciDevicePath (\r
964 Private,\r
965 Bus,\r
966 Device,\r
967 Func,\r
968 *PciDevicePath,\r
969 &PrimaryBus,\r
970 &SubordinateBus\r
971 );\r
972 if (*PciDevicePath == NULL) {\r
973 return EFI_OUT_OF_RESOURCES;\r
974 }\r
975 } while (PrimaryBus != 0xffff);\r
976\r
977 return EFI_SUCCESS;\r
978}\r
979\r
980\r
981/**\r
982 Provides the device-specific addresses needed to access system memory.\r
983\r
984 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
985 @param Operation Indicates if the bus master is going to read or\r
986 write to system memory.\r
987 @param HostAddress The system memory address to map to the device.\r
988 @param NumberOfBytes On input the number of bytes to map. On output the\r
989 number of bytes that were mapped.\r
990 @param DeviceAddress The resulting map address for the bus master\r
991 device to use to access the hosts HostAddress.\r
992 @param Mapping A resulting value to pass to Unmap().\r
993\r
994 @retval EFI_SUCCESS The range was mapped for the returned\r
995 NumberOfBytes.\r
996 @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined.\r
997 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common\r
998 buffer.\r
999 @retval EFI_DEVICE_ERROR The system hardware could not map the requested\r
1000 address.\r
1001 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
1002 of resources.\r
1003\r
1004**/\r
1005EFI_STATUS\r
1006EFIAPI\r
1007DeviceIoMap (\r
1008 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1009 IN EFI_IO_OPERATION_TYPE Operation,\r
1010 IN EFI_PHYSICAL_ADDRESS *HostAddress,\r
1011 IN OUT UINTN *NumberOfBytes,\r
1012 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1013 OUT VOID **Mapping\r
1014 )\r
1015{\r
1016 EFI_STATUS Status;\r
1017 DEVICE_IO_PRIVATE_DATA *Private;\r
1018\r
1019 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1020\r
1021 if (Operation < 0 || Operation > EfiBusMasterCommonBuffer) {\r
1022 return EFI_INVALID_PARAMETER;\r
1023 }\r
1024\r
1025 if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {\r
1026 return EFI_UNSUPPORTED;\r
1027 }\r
1028\r
1029 Status = Private->PciRootBridgeIo->Map (\r
1030 Private->PciRootBridgeIo,\r
1031 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
1032 (VOID *) (UINTN) (*HostAddress),\r
1033 NumberOfBytes,\r
1034 DeviceAddress,\r
1035 Mapping\r
1036 );\r
1037\r
1038 return Status;\r
1039}\r
1040\r
1041\r
1042/**\r
1043 Completes the Map() operation and releases any corresponding resources.\r
1044\r
1045 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1046 @param Mapping The mapping value returned from Map().\r
1047\r
1048 @retval EFI_SUCCESS The range was unmapped.\r
1049 @retval EFI_DEVICE_ERROR The data was not committed to the target system\r
1050 memory.\r
1051\r
1052**/\r
1053EFI_STATUS\r
1054EFIAPI\r
1055DeviceIoUnmap (\r
1056 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1057 IN VOID *Mapping\r
1058 )\r
1059{\r
1060 EFI_STATUS Status;\r
1061 DEVICE_IO_PRIVATE_DATA *Private;\r
1062\r
1063 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1064\r
1065 Status = Private->PciRootBridgeIo->Unmap (\r
1066 Private->PciRootBridgeIo,\r
1067 Mapping\r
1068 );\r
1069\r
1070 return Status;\r
1071}\r
1072\r
1073\r
1074/**\r
1075 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.\r
1076\r
1077 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1078 @param Type The type allocation to perform.\r
1079 @param MemoryType The type of memory to allocate,\r
1080 EfiBootServicesData or EfiRuntimeServicesData.\r
1081 @param Pages The number of pages to allocate.\r
1082 @param PhysicalAddress A pointer to store the base address of the\r
1083 allocated range.\r
1084\r
1085 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1086 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1087 @retval EFI_INVALID_PARAMETER The requested memory type is invalid.\r
1088 @retval EFI_UNSUPPORTED The requested PhysicalAddress is not supported on\r
1089 this platform.\r
1090\r
1091**/\r
1092EFI_STATUS\r
1093EFIAPI\r
1094DeviceIoAllocateBuffer (\r
1095 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1096 IN EFI_ALLOCATE_TYPE Type,\r
1097 IN EFI_MEMORY_TYPE MemoryType,\r
1098 IN UINTN Pages,\r
1099 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r
1100 )\r
1101{\r
6ea838c3 1102 EFI_STATUS Status;\r
1103 EFI_PHYSICAL_ADDRESS HostAddress;\r
1104 DEVICE_IO_PRIVATE_DATA *Private;\r
1105 VOID *HostAddress2;\r
1106\r
1107 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
fd4ae733 1108\r
1109 HostAddress = *PhysicalAddress;\r
1110\r
1111 if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {\r
1112 return EFI_INVALID_PARAMETER;\r
1113 }\r
1114\r
1115 if ((Type >= MaxAllocateType) || (Type < AllocateAnyPages)) {\r
1116 return EFI_INVALID_PARAMETER;\r
1117 }\r
1118\r
1119 if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {\r
1120 return EFI_UNSUPPORTED;\r
1121 }\r
1122\r
1123 if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {\r
1124 Type = AllocateMaxAddress;\r
1125 HostAddress = MAX_COMMON_BUFFER;\r
1126 }\r
1127\r
6ea838c3 1128 HostAddress2 = (VOID *) (UINTN) (HostAddress);\r
1129 Status = Private->PciRootBridgeIo->AllocateBuffer (\r
1130 Private->PciRootBridgeIo,\r
1131 Type,\r
1132 MemoryType,\r
1133 Pages,\r
1134 &HostAddress2,\r
1135 EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
1136 EFI_PCI_ATTRIBUTE_MEMORY_CACHED\r
1137 );\r
1138 \r
fd4ae733 1139 if (EFI_ERROR (Status)) {\r
1140 return Status;\r
1141 }\r
1142\r
1143\r
6ea838c3 1144 *PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress2;\r
fd4ae733 1145\r
1146 return EFI_SUCCESS;\r
1147}\r
1148\r
1149\r
1150/**\r
1151 Flushes any posted write data to the device.\r
1152\r
1153 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1154\r
1155 @retval EFI_SUCCESS The buffers were flushed.\r
1156 @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware\r
1157 error.\r
1158\r
1159**/\r
1160EFI_STATUS\r
1161EFIAPI\r
1162DeviceIoFlush (\r
1163 IN EFI_DEVICE_IO_PROTOCOL *This\r
1164 )\r
1165{\r
1166 EFI_STATUS Status;\r
1167 DEVICE_IO_PRIVATE_DATA *Private;\r
1168\r
1169 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1170\r
1171 Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);\r
1172\r
1173 return Status;\r
1174}\r
1175\r
1176\r
1177/**\r
1178 Frees pages that were allocated with AllocateBuffer().\r
1179\r
1180 @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance.\r
1181 @param Pages The number of pages to free.\r
1182 @param HostAddress The base address of the range to free.\r
1183\r
1184 @retval EFI_SUCCESS The requested memory pages were freed.\r
1185 @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
1186 AllocateBuffer().\r
1187 @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is\r
1188 invalid.\r
1189\r
1190**/\r
1191EFI_STATUS\r
1192EFIAPI\r
1193DeviceIoFreeBuffer (\r
1194 IN EFI_DEVICE_IO_PROTOCOL *This,\r
1195 IN UINTN Pages,\r
1196 IN EFI_PHYSICAL_ADDRESS HostAddress\r
1197 )\r
1198{\r
6ea838c3 1199 DEVICE_IO_PRIVATE_DATA *Private;\r
1200\r
1201 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);\r
1202\r
fd4ae733 1203 if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {\r
1204 return EFI_INVALID_PARAMETER;\r
1205 }\r
1206\r
6ea838c3 1207 return Private->PciRootBridgeIo->FreeBuffer (\r
1208 Private->PciRootBridgeIo,\r
1209 Pages,\r
1210 (VOID *) (UINTN) HostAddress\r
1211 );\r
1212\r
fd4ae733 1213}\r
1214\r