]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c
MdeModulePkg XhciPei: Remove redundant functions
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciPei / UsbHcMem.c
CommitLineData
d987459f
SZ
1/** @file\r
2PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
3which is used to enable recovery function from USB Drivers.\r
4\r
2048c585 5Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
d987459f
SZ
6\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions\r
9of the BSD License which accompanies this distribution. The\r
10full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "XhcPeim.h"\r
19\r
20/**\r
21 Allocate a block of memory to be used by the buffer pool.\r
22\r
23 @param Pages How many pages to allocate.\r
24\r
25 @return Pointer to the allocated memory block or NULL if failed.\r
26\r
27**/\r
28USBHC_MEM_BLOCK *\r
29UsbHcAllocMemBlock (\r
30 IN UINTN Pages\r
31 )\r
32{\r
33 USBHC_MEM_BLOCK *Block;\r
b575ca32
JY
34 VOID *BufHost;\r
35 VOID *Mapping;\r
36 EFI_PHYSICAL_ADDRESS MappedAddr;\r
d987459f
SZ
37 EFI_STATUS Status;\r
38 UINTN PageNumber;\r
39 EFI_PHYSICAL_ADDRESS TempPtr;\r
40\r
41 PageNumber = EFI_SIZE_TO_PAGES (sizeof (USBHC_MEM_BLOCK));\r
42 Status = PeiServicesAllocatePages (\r
43 EfiBootServicesData,\r
44 PageNumber,\r
45 &TempPtr\r
46 );\r
47\r
48 if (EFI_ERROR (Status)) {\r
49 return NULL;\r
50 }\r
51 ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber));\r
52\r
53 //\r
54 // each bit in the bit array represents USBHC_MEM_UNIT\r
55 // bytes of memory in the memory block.\r
56 //\r
57 ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);\r
58\r
59 Block = (USBHC_MEM_BLOCK *) (UINTN) TempPtr;\r
60 Block->BufLen = EFI_PAGES_TO_SIZE (Pages);\r
61 Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);\r
62\r
63 PageNumber = EFI_SIZE_TO_PAGES (Block->BitsLen);\r
64 Status = PeiServicesAllocatePages (\r
65 EfiBootServicesData,\r
66 PageNumber,\r
67 &TempPtr\r
68 );\r
69\r
70 if (EFI_ERROR (Status)) {\r
71 return NULL;\r
72 }\r
73 ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber));\r
74\r
75 Block->Bits = (UINT8 *) (UINTN) TempPtr;\r
76\r
b575ca32 77 Status = IoMmuAllocateBuffer (\r
d987459f 78 Pages,\r
b575ca32
JY
79 &BufHost,\r
80 &MappedAddr,\r
81 &Mapping\r
d987459f
SZ
82 );\r
83 if (EFI_ERROR (Status)) {\r
84 return NULL;\r
85 }\r
b575ca32 86 ZeroMem ((VOID *) (UINTN) BufHost, EFI_PAGES_TO_SIZE (Pages));\r
d987459f 87\r
b575ca32
JY
88 Block->BufHost = (UINT8 *) (UINTN) BufHost;\r
89 Block->Buf = (UINT8 *) (UINTN) MappedAddr;\r
90 Block->Mapping = Mapping;\r
d987459f
SZ
91 Block->Next = NULL;\r
92\r
93 return Block;\r
94}\r
95\r
96/**\r
97 Free the memory block from the memory pool.\r
98\r
99 @param Pool The memory pool to free the block from.\r
100 @param Block The memory block to free.\r
101\r
102**/\r
103VOID\r
104UsbHcFreeMemBlock (\r
105 IN USBHC_MEM_POOL *Pool,\r
106 IN USBHC_MEM_BLOCK *Block\r
107 )\r
108{\r
109 ASSERT ((Pool != NULL) && (Block != NULL));\r
b575ca32
JY
110\r
111 IoMmuFreeBuffer (EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost, Block->Mapping);\r
112\r
d987459f
SZ
113 //\r
114 // No free memory in PEI.\r
115 //\r
116}\r
117\r
118/**\r
119 Alloc some memory from the block.\r
120\r
121 @param Block The memory block to allocate memory from.\r
122 @param Units Number of memory units to allocate.\r
123\r
124 @return The pointer to the allocated memory.\r
125 If couldn't allocate the needed memory, the return value is NULL.\r
126\r
127**/\r
128VOID *\r
129UsbHcAllocMemFromBlock (\r
130 IN USBHC_MEM_BLOCK *Block,\r
131 IN UINTN Units\r
132 )\r
133{\r
134 UINTN Byte;\r
135 UINT8 Bit;\r
136 UINTN StartByte;\r
137 UINT8 StartBit;\r
138 UINTN Available;\r
139 UINTN Count;\r
140\r
141 ASSERT ((Block != 0) && (Units != 0));\r
142\r
143 StartByte = 0;\r
144 StartBit = 0;\r
145 Available = 0;\r
146\r
147 for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {\r
148 //\r
149 // If current bit is zero, the corresponding memory unit is\r
150 // available, otherwise we need to restart our searching.\r
151 // Available counts the consective number of zero bit.\r
152 //\r
153 if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {\r
154 Available++;\r
155\r
156 if (Available >= Units) {\r
157 break;\r
158 }\r
159\r
160 NEXT_BIT (Byte, Bit);\r
161 } else {\r
162 NEXT_BIT (Byte, Bit);\r
163\r
164 Available = 0;\r
165 StartByte = Byte;\r
166 StartBit = Bit;\r
167 }\r
168 }\r
169\r
170 if (Available < Units) {\r
171 return NULL;\r
172 }\r
173\r
174 //\r
175 // Mark the memory as allocated\r
176 //\r
177 Byte = StartByte;\r
178 Bit = StartBit;\r
179\r
180 for (Count = 0; Count < Units; Count++) {\r
181 ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));\r
182\r
183 Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit));\r
184 NEXT_BIT (Byte, Bit);\r
185 }\r
186\r
187 return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
188}\r
189\r
190/**\r
191 Calculate the corresponding pci bus address according to the Mem parameter.\r
192\r
193 @param Pool The memory pool of the host controller.\r
194 @param Mem The pointer to host memory.\r
195 @param Size The size of the memory region.\r
196\r
197 @return The pci memory address\r
198\r
199**/\r
200EFI_PHYSICAL_ADDRESS\r
201UsbHcGetPciAddrForHostAddr (\r
202 IN USBHC_MEM_POOL *Pool,\r
203 IN VOID *Mem,\r
204 IN UINTN Size\r
205 )\r
206{\r
207 USBHC_MEM_BLOCK *Head;\r
208 USBHC_MEM_BLOCK *Block;\r
209 UINTN AllocSize;\r
210 EFI_PHYSICAL_ADDRESS PhyAddr;\r
211 UINTN Offset;\r
212\r
213 Head = Pool->Head;\r
214 AllocSize = USBHC_MEM_ROUND (Size);\r
215\r
216 if (Mem == NULL) {\r
217 return 0;\r
218 }\r
219\r
220 for (Block = Head; Block != NULL; Block = Block->Next) {\r
221 //\r
222 // scan the memory block list for the memory block that\r
223 // completely contains the allocated memory.\r
224 //\r
225 if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
226 break;\r
227 }\r
228 }\r
229\r
230 ASSERT ((Block != NULL));\r
231 //\r
232 // calculate the pci memory address for host memory address.\r
233 //\r
234 Offset = (UINT8 *) Mem - Block->BufHost;\r
235 PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) (Block->Buf + Offset);\r
236 return PhyAddr;\r
237}\r
238\r
239/**\r
240 Calculate the corresponding host address according to the pci address.\r
241\r
242 @param Pool The memory pool of the host controller.\r
243 @param Mem The pointer to pci memory.\r
244 @param Size The size of the memory region.\r
245\r
246 @return The host memory address\r
247\r
248**/\r
249EFI_PHYSICAL_ADDRESS\r
250UsbHcGetHostAddrForPciAddr (\r
251 IN USBHC_MEM_POOL *Pool,\r
252 IN VOID *Mem,\r
253 IN UINTN Size\r
254 )\r
255{\r
256 USBHC_MEM_BLOCK *Head;\r
257 USBHC_MEM_BLOCK *Block;\r
258 UINTN AllocSize;\r
259 EFI_PHYSICAL_ADDRESS HostAddr;\r
260 UINTN Offset;\r
261\r
262 Head = Pool->Head;\r
263 AllocSize = USBHC_MEM_ROUND (Size);\r
264\r
265 if (Mem == NULL) {\r
266 return 0;\r
267 }\r
268\r
269 for (Block = Head; Block != NULL; Block = Block->Next) {\r
270 //\r
271 // scan the memory block list for the memory block that\r
272 // completely contains the allocated memory.\r
273 //\r
274 if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + Block->BufLen))) {\r
275 break;\r
276 }\r
277 }\r
278\r
279 ASSERT ((Block != NULL));\r
280 //\r
281 // calculate the host memory address for pci memory address.\r
282 //\r
283 Offset = (UINT8 *) Mem - Block->Buf;\r
284 HostAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) (Block->BufHost + Offset);\r
285 return HostAddr;\r
286}\r
287\r
288/**\r
289 Insert the memory block to the pool's list of the blocks.\r
290\r
291 @param Head The head of the memory pool's block list.\r
292 @param Block The memory block to insert.\r
293\r
294**/\r
295VOID\r
296UsbHcInsertMemBlockToPool (\r
297 IN USBHC_MEM_BLOCK *Head,\r
298 IN USBHC_MEM_BLOCK *Block\r
299 )\r
300{\r
301 ASSERT ((Head != NULL) && (Block != NULL));\r
302 Block->Next = Head->Next;\r
303 Head->Next = Block;\r
304}\r
305\r
306/**\r
307 Is the memory block empty?\r
308\r
309 @param Block The memory block to check.\r
310\r
311 @retval TRUE The memory block is empty.\r
312 @retval FALSE The memory block isn't empty.\r
313\r
314**/\r
315BOOLEAN\r
316UsbHcIsMemBlockEmpty (\r
317 IN USBHC_MEM_BLOCK *Block\r
318 )\r
319{\r
320 UINTN Index;\r
321\r
322 for (Index = 0; Index < Block->BitsLen; Index++) {\r
323 if (Block->Bits[Index] != 0) {\r
324 return FALSE;\r
325 }\r
326 }\r
327\r
328 return TRUE;\r
329}\r
330\r
d987459f 331\r
d987459f
SZ
332\r
333/**\r
334 Initialize the memory management pool for the host controller.\r
335\r
336 @return Pointer to the allocated memory pool or NULL if failed.\r
337\r
338**/\r
339USBHC_MEM_POOL *\r
340UsbHcInitMemPool (\r
341 VOID\r
342 )\r
343{\r
344 USBHC_MEM_POOL *Pool;\r
345 UINTN PageNumber;\r
346 EFI_STATUS Status;\r
347 EFI_PHYSICAL_ADDRESS TempPtr;\r
348\r
349 PageNumber = EFI_SIZE_TO_PAGES (sizeof (USBHC_MEM_POOL));\r
350 Status = PeiServicesAllocatePages (\r
351 EfiBootServicesData,\r
352 PageNumber,\r
353 &TempPtr\r
354 );\r
355 if (EFI_ERROR (Status)) {\r
356 return NULL;\r
357 }\r
358 ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber));\r
359\r
360 Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr);\r
361 Pool->Head = UsbHcAllocMemBlock (USBHC_MEM_DEFAULT_PAGES);\r
362\r
363 if (Pool->Head == NULL) {\r
364 //\r
365 // No free memory in PEI.\r
366 //\r
367 Pool = NULL;\r
368 }\r
369\r
370 return Pool;\r
371}\r
372\r
373/**\r
374 Release the memory management pool.\r
375\r
376 @param Pool The USB memory pool to free.\r
377\r
378**/\r
379VOID\r
380UsbHcFreeMemPool (\r
381 IN USBHC_MEM_POOL *Pool\r
382 )\r
383{\r
384 USBHC_MEM_BLOCK *Block;\r
385\r
386 ASSERT (Pool->Head != NULL);\r
387\r
388 //\r
389 // Unlink all the memory blocks from the pool, then free them.\r
390 // UsbHcUnlinkMemBlock can't be used to unlink and free the\r
391 // first block.\r
392 //\r
393 for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {\r
394 //UsbHcUnlinkMemBlock (Pool->Head, Block);\r
395 UsbHcFreeMemBlock (Pool, Block);\r
396 }\r
397\r
398 UsbHcFreeMemBlock (Pool, Pool->Head);\r
399}\r
400\r
401/**\r
402 Allocate some memory from the host controller's memory pool\r
403 which can be used to communicate with host controller.\r
404\r
405 @param Pool The host controller's memory pool.\r
406 @param Size Size of the memory to allocate.\r
407\r
408 @return The allocated memory or NULL.\r
409\r
410**/\r
411VOID *\r
412UsbHcAllocateMem (\r
413 IN USBHC_MEM_POOL *Pool,\r
414 IN UINTN Size\r
415 )\r
416{\r
417 USBHC_MEM_BLOCK *Head;\r
418 USBHC_MEM_BLOCK *Block;\r
419 USBHC_MEM_BLOCK *NewBlock;\r
420 VOID *Mem;\r
421 UINTN AllocSize;\r
422 UINTN Pages;\r
423\r
424 Mem = NULL;\r
425 AllocSize = USBHC_MEM_ROUND (Size);\r
426 Head = Pool->Head;\r
427 ASSERT (Head != NULL);\r
428\r
429 //\r
430 // First check whether current memory blocks can satisfy the allocation.\r
431 //\r
432 for (Block = Head; Block != NULL; Block = Block->Next) {\r
433 Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);\r
434\r
435 if (Mem != NULL) {\r
436 ZeroMem (Mem, Size);\r
437 break;\r
438 }\r
439 }\r
440\r
441 if (Mem != NULL) {\r
442 return Mem;\r
443 }\r
444\r
445 //\r
446 // Create a new memory block if there is not enough memory\r
447 // in the pool. If the allocation size is larger than the\r
448 // default page number, just allocate a large enough memory\r
449 // block. Otherwise allocate default pages.\r
450 //\r
451 if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {\r
452 Pages = EFI_SIZE_TO_PAGES (AllocSize);\r
453 } else {\r
454 Pages = USBHC_MEM_DEFAULT_PAGES;\r
455 }\r
456 NewBlock = UsbHcAllocMemBlock (Pages);\r
457\r
458 if (NewBlock == NULL) {\r
459 return NULL;\r
460 }\r
461\r
462 //\r
463 // Add the new memory block to the pool, then allocate memory from it\r
464 //\r
465 UsbHcInsertMemBlockToPool (Head, NewBlock);\r
466 Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);\r
467\r
468 if (Mem != NULL) {\r
469 ZeroMem (Mem, Size);\r
470 }\r
471\r
472 return Mem;\r
473}\r
474\r
475/**\r
476 Free the allocated memory back to the memory pool.\r
477\r
478 @param Pool The memory pool of the host controller.\r
479 @param Mem The memory to free.\r
480 @param Size The size of the memory to free.\r
481\r
482**/\r
483VOID\r
484UsbHcFreeMem (\r
485 IN USBHC_MEM_POOL *Pool,\r
486 IN VOID *Mem,\r
487 IN UINTN Size\r
488 )\r
489{\r
490 USBHC_MEM_BLOCK *Head;\r
491 USBHC_MEM_BLOCK *Block;\r
492 UINT8 *ToFree;\r
493 UINTN AllocSize;\r
494 UINTN Byte;\r
495 UINTN Bit;\r
496 UINTN Count;\r
497\r
498 Head = Pool->Head;\r
499 AllocSize = USBHC_MEM_ROUND (Size);\r
500 ToFree = (UINT8 *) Mem;\r
501\r
502 for (Block = Head; Block != NULL; Block = Block->Next) {\r
503 //\r
504 // scan the memory block list for the memory block that\r
505 // completely contains the memory to free.\r
506 //\r
507 if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
508 //\r
509 // compute the start byte and bit in the bit array\r
510 //\r
511 Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;\r
512 Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;\r
513\r
514 //\r
2048c585 515 // reset associated bits in bit array\r
d987459f
SZ
516 //\r
517 for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {\r
518 ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));\r
519\r
520 Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));\r
521 NEXT_BIT (Byte, Bit);\r
522 }\r
523\r
524 break;\r
525 }\r
526 }\r
527\r
528 //\r
529 // If Block == NULL, it means that the current memory isn't\r
530 // in the host controller's pool. This is critical because\r
531 // the caller has passed in a wrong memory pointer\r
532 //\r
533 ASSERT (Block != NULL);\r
534\r
535 //\r
536 // Release the current memory block if it is empty and not the head\r
537 //\r
538 if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {\r
539 //UsbHcUnlinkMemBlock (Head, Block);\r
540 UsbHcFreeMemBlock (Pool, Block);\r
541 }\r
542}\r
543\r
544/**\r
545 Allocates pages at a specified alignment.\r
546\r
547 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
548\r
549 @param Pages The number of pages to allocate.\r
550 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
551 @param HostAddress The system memory address to map to the PCI controller.\r
552 @param DeviceAddress The resulting map address for the bus master PCI controller to\r
553 use to access the hosts HostAddress.\r
b575ca32 554 @param Mapping A resulting value to pass to Unmap().\r
d987459f
SZ
555\r
556 @retval EFI_SUCCESS Success to allocate aligned pages.\r
557 @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid.\r
558 @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory.\r
559\r
560**/\r
561EFI_STATUS\r
562UsbHcAllocateAlignedPages (\r
563 IN UINTN Pages,\r
564 IN UINTN Alignment,\r
565 OUT VOID **HostAddress,\r
b575ca32
JY
566 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
567 OUT VOID **Mapping\r
d987459f
SZ
568 )\r
569{\r
570 EFI_STATUS Status;\r
b575ca32 571 VOID *Memory;\r
d987459f
SZ
572 UINTN AlignedMemory;\r
573 UINTN AlignmentMask;\r
b575ca32
JY
574 EFI_PHYSICAL_ADDRESS DeviceMemory;\r
575 UINTN AlignedDeviceMemory;\r
d987459f
SZ
576 UINTN RealPages;\r
577\r
578 //\r
579 // Alignment must be a power of two or zero.\r
580 //\r
581 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
582\r
583 if ((Alignment & (Alignment - 1)) != 0) {\r
584 return EFI_INVALID_PARAMETER;\r
585 }\r
586\r
587 if (Pages == 0) {\r
588 return EFI_INVALID_PARAMETER;\r
589 }\r
590\r
591 if (Alignment > EFI_PAGE_SIZE) {\r
592 //\r
e50a226b 593 // Calculate the total number of pages since alignment is larger than page size.\r
d987459f
SZ
594 //\r
595 AlignmentMask = Alignment - 1;\r
596 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
597 //\r
598 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
599 //\r
600 ASSERT (RealPages > Pages);\r
601\r
b575ca32 602 Status = IoMmuAllocateBuffer (\r
d987459f 603 Pages,\r
b575ca32
JY
604 &Memory,\r
605 &DeviceMemory,\r
606 Mapping\r
d987459f
SZ
607 );\r
608 if (EFI_ERROR (Status)) {\r
609 return EFI_OUT_OF_RESOURCES;\r
610 }\r
611 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
b575ca32 612 AlignedDeviceMemory = ((UINTN) DeviceMemory + AlignmentMask) & ~AlignmentMask;\r
d987459f
SZ
613 } else {\r
614 //\r
615 // Do not over-allocate pages in this case.\r
616 //\r
b575ca32 617 Status = IoMmuAllocateBuffer (\r
d987459f 618 Pages,\r
b575ca32
JY
619 &Memory,\r
620 &DeviceMemory,\r
621 Mapping\r
d987459f
SZ
622 );\r
623 if (EFI_ERROR (Status)) {\r
624 return EFI_OUT_OF_RESOURCES;\r
625 }\r
626 AlignedMemory = (UINTN) Memory;\r
b575ca32 627 AlignedDeviceMemory = (UINTN) DeviceMemory;\r
d987459f
SZ
628 }\r
629\r
630 *HostAddress = (VOID *) AlignedMemory;\r
b575ca32 631 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) AlignedDeviceMemory;\r
d987459f
SZ
632\r
633 return EFI_SUCCESS;\r
634}\r
635\r
636/**\r
637 Frees memory that was allocated with UsbHcAllocateAlignedPages().\r
638\r
639 @param HostAddress The system memory address to map to the PCI controller.\r
640 @param Pages The number of pages to free.\r
b575ca32 641 @param Mapping The mapping value returned from Map().\r
d987459f
SZ
642\r
643**/\r
644VOID\r
645UsbHcFreeAlignedPages (\r
646 IN VOID *HostAddress,\r
b575ca32
JY
647 IN UINTN Pages,\r
648 IN VOID *Mapping\r
d987459f
SZ
649 )\r
650{\r
651 ASSERT (Pages != 0);\r
b575ca32
JY
652\r
653 IoMmuFreeBuffer (Pages, HostAddress, Mapping);\r
d987459f
SZ
654}\r
655\r