Add some comments for translator parameter in Sync/AsyncInterruptTransfer.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / Ehci / Dxe / EhciMem.c
CommitLineData
562d2849 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 EhciMem.c\r
15 \r
16Abstract: \r
17 \r
18\r
19Revision History\r
20--*/\r
21\r
22#include "Ehci.h"\r
23\r
24\r
25EFI_STATUS\r
26CreateMemoryBlock (\r
27 IN USB2_HC_DEV *HcDev,\r
28 OUT MEMORY_MANAGE_HEADER **MemoryHeader,\r
29 IN UINTN MemoryBlockSizeInPages\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34\r
35 Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
36 and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
37\r
38Arguments:\r
39\r
40 HcDev - USB2_HC_DEV\r
41 MemoryHeader - MEMORY_MANAGE_HEADER to output\r
42 MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
43 \r
44Returns:\r
45\r
46 EFI_SUCCESS Success\r
47 EFI_OUT_OF_RESOURCES Fail for no resources\r
48 EFI_UNSUPPORTED Unsupported currently\r
49 \r
50--*/\r
51{\r
52 EFI_STATUS Status;\r
53 VOID *CommonBuffer;\r
54 EFI_PHYSICAL_ADDRESS MappedAddress;\r
55 UINTN MemoryBlockSizeInBytes;\r
56 VOID *Mapping;\r
57\r
58 //\r
59 // Allocate memory for MemoryHeader\r
60 //\r
61 *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));\r
62 if (*MemoryHeader == NULL) {\r
63 return EFI_OUT_OF_RESOURCES;\r
64 }\r
65\r
66 (*MemoryHeader)->Next = NULL;\r
67\r
68 //\r
69 // set Memory block size\r
70 //\r
71 (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
72\r
73 //\r
74 // each bit in Bit Array will manage 32 bytes memory in memory block\r
75 //\r
76 (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;\r
77\r
78 //\r
79 // Allocate memory for BitArray\r
80 //\r
81 (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);\r
82 if ((*MemoryHeader)->BitArrayPtr == NULL) {\r
83 gBS->FreePool (*MemoryHeader);\r
84 return EFI_OUT_OF_RESOURCES;\r
85 }\r
86 \r
87 //\r
88 // Memory Block uses MemoryBlockSizeInPages pages,\r
89 // and it is allocated as common buffer use.\r
90 //\r
91 Status = HcDev->PciIo->AllocateBuffer (\r
92 HcDev->PciIo,\r
93 AllocateAnyPages,\r
94 EfiBootServicesData,\r
95 MemoryBlockSizeInPages,\r
96 &CommonBuffer,\r
97 0\r
98 );\r
99 if (EFI_ERROR (Status)) {\r
100 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
101 gBS->FreePool (*MemoryHeader);\r
102 return EFI_OUT_OF_RESOURCES;\r
103 }\r
104\r
105 MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
106 Status = HcDev->PciIo->Map (\r
107 HcDev->PciIo,\r
108 EfiPciIoOperationBusMasterCommonBuffer,\r
109 CommonBuffer,\r
110 &MemoryBlockSizeInBytes,\r
111 &MappedAddress,\r
112 &Mapping\r
113 );\r
114 //\r
115 // If returned Mapped size is less than the size \r
116 // we request,do not support.\r
117 //\r
118 if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {\r
119 HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
120 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
121 gBS->FreePool (*MemoryHeader);\r
122 return EFI_UNSUPPORTED;\r
123 }\r
124 \r
125 //\r
126 // Data structure involved by host controller \r
127 // should be restricted into the same 4G\r
128 //\r
129 if (HcDev->Is64BitCapable != 0) {\r
130 if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {\r
131 HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
132 HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
133 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
134 gBS->FreePool (*MemoryHeader);\r
135 return EFI_UNSUPPORTED;\r
136 }\r
137 }\r
138 \r
139 //\r
140 // Set Memory block initial address\r
141 //\r
142 (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);\r
143 (*MemoryHeader)->Mapping = Mapping;\r
144\r
145 ZeroMem (\r
146 (*MemoryHeader)->MemoryBlockPtr,\r
147 EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)\r
148 );\r
149\r
150 return EFI_SUCCESS;\r
151}\r
152\r
153EFI_STATUS\r
154FreeMemoryHeader (\r
155 IN USB2_HC_DEV *HcDev,\r
156 IN MEMORY_MANAGE_HEADER *MemoryHeader\r
157 )\r
158/*++\r
159\r
160Routine Description:\r
161\r
162 Free Memory Header\r
163\r
164Arguments:\r
165\r
166 HcDev - USB2_HC_DEV\r
167 MemoryHeader - MemoryHeader to be freed\r
168\r
169Returns:\r
170\r
171 EFI_SUCCESS Success\r
172 EFI_INVALID_PARAMETER Parameter is error\r
173\r
174--*/\r
175{\r
176 if ((MemoryHeader == NULL) || (HcDev == NULL)) {\r
177 return EFI_INVALID_PARAMETER;\r
178 }\r
179 //\r
180 // unmap the common buffer used by the memory block\r
181 //\r
182 HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);\r
183\r
184 //\r
185 // free common buffer\r
186 //\r
187 HcDev->PciIo->FreeBuffer (\r
188 HcDev->PciIo,\r
189 EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),\r
190 MemoryHeader->MemoryBlockPtr\r
191 );\r
192 //\r
193 // free bit array\r
194 //\r
195 gBS->FreePool (MemoryHeader->BitArrayPtr);\r
196 //\r
197 // free memory header\r
198 //\r
199 gBS->FreePool (MemoryHeader);\r
200\r
201 return EFI_SUCCESS;\r
202}\r
203\r
204EFI_STATUS\r
205EhciAllocatePool (\r
206 IN USB2_HC_DEV *HcDev,\r
207 OUT UINT8 **Pool,\r
208 IN UINTN AllocSize\r
209 )\r
210/*++\r
211\r
212Routine Description:\r
213\r
214 Ehci Allocate Pool\r
215\r
216Arguments:\r
217\r
218 HcDev - USB2_HC_DEV\r
219 Pool - Place to store pointer to the memory buffer\r
220 AllocSize - Alloc Size\r
221\r
222Returns:\r
223\r
224 EFI_SUCCESS Success\r
225 EFI_DEVICE_ERROR Fail\r
226\r
227--*/\r
228{\r
229 MEMORY_MANAGE_HEADER *MemoryHeader;\r
230 MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
231 MEMORY_MANAGE_HEADER *NewMemoryHeader;\r
232 UINTN RealAllocSize;\r
233 UINTN MemoryBlockSizeInPages;\r
234 EFI_STATUS Status;\r
235 EFI_TPL OldTpl;\r
236\r
237 *Pool = NULL;\r
238\r
239 MemoryHeader = HcDev->MemoryHeader;\r
240 ASSERT (MemoryHeader != NULL);\r
241\r
242 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
243 \r
244 //\r
245 // allocate unit is 32 bytes (align on 32 byte)\r
246 //\r
247 if (AllocSize & 0x1F) {\r
248 RealAllocSize = (AllocSize / 32 + 1) * 32;\r
249 } else {\r
250 RealAllocSize = AllocSize;\r
251 }\r
252 \r
253 //\r
254 // There may be linked MemoryHeaders.\r
255 // To allocate a free pool in Memory blocks,\r
256 // must search in the MemoryHeader link list\r
257 // until enough free pool is found.\r
258 //\r
259 Status = EFI_NOT_FOUND;\r
260 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
261\r
262 Status = AllocMemInMemoryBlock (\r
263 TempHeaderPtr,\r
264 Pool,\r
265 RealAllocSize / 32\r
266 );\r
267 if (!EFI_ERROR (Status)) {\r
268 ZeroMem (*Pool, AllocSize);\r
269 gBS->RestoreTPL (OldTpl);\r
270 return EFI_SUCCESS;\r
271 }\r
272 }\r
273\r
274 gBS->RestoreTPL (OldTpl);\r
275 \r
276 //\r
277 // There is no enough memory,\r
278 // Create a new Memory Block\r
279 //\r
280 \r
281 //\r
282 // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,\r
283 // just allocate a large enough memory block.\r
284 //\r
285 if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {\r
286 MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;\r
287 } else {\r
288 MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
289 }\r
290\r
291 Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);\r
292 if (EFI_ERROR (Status)) {\r
293 return Status;\r
294 }\r
295\r
296 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r\r
297 \r
298 //\r
299 // Link the new Memory Block to the Memory Header list\r
300 //\r
301 InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
302\r
303 Status = AllocMemInMemoryBlock (\r
304 NewMemoryHeader,\r
305 Pool,\r
306 RealAllocSize / 32\r
307 );\r
308 if (!EFI_ERROR (Status)) {\r
309 ZeroMem (*Pool, AllocSize);\r
310 }\r
311\r
312 gBS->RestoreTPL (OldTpl);\r
313 return Status;\r
314}\r
315\r
316VOID\r
317EhciFreePool (\r
318 IN USB2_HC_DEV *HcDev,\r
319 IN UINT8 *Pool,\r
320 IN UINTN AllocSize\r
321 )\r
322/*++\r
323\r
324Routine Description:\r
325\r
326 Uhci Free Pool\r
327\r
328Arguments:\r
329\r
330 HcDev - USB_HC_DEV\r
331 Pool - Pool to free\r
332 AllocSize - Pool size\r
333\r
334Returns:\r
335\r
336 VOID\r
337\r
338--*/\r
339{\r
340 MEMORY_MANAGE_HEADER *MemoryHeader;\r
341 MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
342 UINTN StartBytePos;\r
343 UINTN Index;\r
344 UINT8 StartBitPos;\r
345 UINT8 Index2;\r
346 UINTN Count;\r
347 UINTN RealAllocSize;\r
348 EFI_TPL OldTpl;\r
349\r
350 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
351\r
352 MemoryHeader = HcDev->MemoryHeader;\r
353\r
354 //\r
355 // allocate unit is 32 byte (align on 32 byte)\r
356 //\r
357 if (AllocSize & 0x1F) {\r
358 RealAllocSize = (AllocSize / 32 + 1) * 32;\r
359 } else {\r
360 RealAllocSize = AllocSize;\r
361 }\r
362 \r
363 //\r
364 // scan the memory header linked list for\r
365 // the asigned memory to free.\r
366 //\r
367 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
368\r
369 if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&\r
370 ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))\r
371 ) {\r
372 //\r
373 // Pool is in the Memory Block area,\r
374 // find the start byte and bit in the bit array\r
375 //\r
376 StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;\r
377 StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);\r
378\r
379 //\r
380 // reset associated bits in bit arry\r
381 //\r
382 for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {\r
383 TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));\r
384 Index2++;\r
385 if (Index2 == 8) {\r
386 Index += 1;\r
387 Index2 = 0;\r
388 }\r
389 }\r
390 //\r
391 // break the loop\r
392 //\r
393 break;\r
394 }\r
395 }\r
396 \r
397 //\r
398 // Release emptied memory blocks (only if the memory block is not\r
399 // the first one in the memory header list\r
400 //\r
401 for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
402\r
403 ASSERT (MemoryHeader->Next != NULL);\r
404\r
405 if (IsMemoryBlockEmptied (TempHeaderPtr)) {\r
406\r
407 DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);\r
408 //\r
409 // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
410 // the TempHeaderPtr is pointing to nonsense content.\r
411 //\r
412 gBS->RestoreTPL (OldTpl);\r
413 FreeMemoryHeader (HcDev, TempHeaderPtr);\r
414 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
415 //\r
416 // reset the TempHeaderPtr, continue search for\r
417 // another empty memory block.\r
418 //\r
419 TempHeaderPtr = MemoryHeader->Next;\r
420 continue;\r
421 }\r
422\r
423 TempHeaderPtr = TempHeaderPtr->Next;\r
424 }\r
425\r
426 gBS->RestoreTPL (OldTpl);\r
427}\r
428\r
429VOID\r
430InsertMemoryHeaderToList (\r
431 IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
432 IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
433 )\r
434/*++\r
435\r
436Routine Description:\r
437\r
438 Insert Memory Header To List\r
439\r
440Arguments:\r
441\r
442 MemoryHeader - MEMORY_MANAGE_HEADER\r
443 NewMemoryHeader - MEMORY_MANAGE_HEADER\r
444\r
445Returns:\r
446\r
447 VOID\r
448\r
449--*/\r
450{\r
451 MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
452\r
453 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
454 if (TempHeaderPtr->Next == NULL) {\r
455 TempHeaderPtr->Next = NewMemoryHeader;\r
456 break;\r
457 }\r
458 }\r
459}\r
460\r
461EFI_STATUS\r
462AllocMemInMemoryBlock (\r
463 IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
464 OUT VOID **Pool,\r
465 IN UINTN NumberOfMemoryUnit\r
466 )\r
467/*++\r
468\r
469Routine Description:\r
470\r
471 Alloc Memory In MemoryBlock\r
472\r
473Arguments:\r
474\r
475 MemoryHeader - MEMORY_MANAGE_HEADER\r
476 Pool - Place to store pointer to memory\r
477 NumberOfMemoryUnit - Number Of Memory Unit\r
478\r
479Returns:\r
480\r
481 EFI_SUCCESS Success\r
482 EFI_NOT_FOUND Can't find the free memory \r
483\r
484--*/\r
485{\r
486 UINTN TempBytePos;\r
487 UINTN FoundBytePos;\r
488 UINT8 Index;\r
489 UINT8 FoundBitPos;\r
490 UINT8 ByteValue;\r
491 UINT8 BitValue;\r
492 UINTN NumberOfZeros;\r
493 UINTN Count;\r
494\r
495 FoundBytePos = 0;\r
496 FoundBitPos = 0;\r
497 ByteValue = MemoryHeader->BitArrayPtr[0];\r
498 NumberOfZeros = 0;\r
499 Index = 0;\r
500\r
501 for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {\r
502 \r
503 //\r
504 // Pop out BitValue from a byte in TempBytePos.\r
505 //\r
506 BitValue = (UINT8) (ByteValue & 0x1);\r
507 \r
508 //\r
509 // right shift the byte\r
510 //\r
511 ByteValue /= 2;\r
512\r
513 if (BitValue == 0) {\r
514 //\r
515 // Found a free bit, the NumberOfZeros only record the number\r
516 // of those consecutive zeros\r
517 //\r
518 NumberOfZeros++;\r
519 //\r
520 // Found enough consecutive free space, break the loop\r
521 //\r
522 if (NumberOfZeros >= NumberOfMemoryUnit) {\r
523 break;\r
524 }\r
525 } else {\r
526 //\r
527 // Encountering a '1', meant the bit is ocupied.\r
528 //\r
529 if (NumberOfZeros >= NumberOfMemoryUnit) {\r
530 //\r
531 // Found enough consecutive free space,break the loop\r
532 //\r
533 break;\r
534 } else {\r
535 //\r
536 // the NumberOfZeros only record the number of those consecutive zeros,\r
537 // so reset the NumberOfZeros to 0 when encountering '1' before finding\r
538 // enough consecutive '0's\r
539 //\r
540 NumberOfZeros = 0;\r
541 //\r
542 // reset the (FoundBytePos,FoundBitPos) to the position of '1'\r
543 //\r
544 FoundBytePos = TempBytePos;\r
545 FoundBitPos = Index;\r
546 }\r
547 }\r
548 \r
549 //\r
550 // step forward a bit\r
551 //\r
552 Index++;\r
553 if (Index == 8) {\r
554 //\r
555 // step forward a byte, getting the byte value,\r
556 // and reset the bit pos.\r
557 //\r
558 TempBytePos += 1;\r
559 ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];\r
560 Index = 0;\r
561 }\r
562 }\r
563\r
564 if (NumberOfZeros < NumberOfMemoryUnit) {\r
565 return EFI_NOT_FOUND;\r
566 }\r
567 \r
568 //\r
569 // Found enough free space.\r
570 //\r
571 \r
572 //\r
573 // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:\r
574 // 1)(FoundBytePos,FoundBitPos) record the position\r
575 // of the last '1' before the consecutive '0's, it must\r
576 // be adjusted to the start position of the consecutive '0's.\r
577 // 2)the start address of the consecutive '0's is just the start of\r
578 // the bitarray. so no need to adjust the values of\r
579 // (FoundBytePos,FoundBitPos).\r
580 //\r
581 if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {\r
582 FoundBitPos += 1;\r
583 }\r
584 \r
585 //\r
586 // Have the (FoundBytePos,FoundBitPos) make sense.\r
587 //\r
588 if (FoundBitPos > 7) {\r
589 FoundBytePos += 1;\r
590 FoundBitPos -= 8;\r
591 }\r
592 \r
593 //\r
594 // Set the memory as allocated\r
595 //\r
596 for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {\r
597\r
598 MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);\r
599 Index++;\r
600 if (Index == 8) {\r
601 TempBytePos += 1;\r
602 Index = 0;\r
603 }\r
604 }\r
605\r
606 *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;\r
607\r
608 return EFI_SUCCESS;\r
609}\r
610\r
611BOOLEAN\r
612IsMemoryBlockEmptied (\r
613 IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
614 )\r
615/*++\r
616\r
617Routine Description:\r
618\r
619 Is Memory Block Emptied\r
620\r
621Arguments:\r
622\r
623 MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
624\r
625Returns:\r
626\r
627 TRUE Empty\r
628 FALSE Not Empty \r
629\r
630--*/\r
631{\r
632 UINTN Index;\r
633\r
634 for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
635 if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
636 return FALSE;\r
637 }\r
638 }\r
639\r
640 return TRUE;\r
641}\r
642\r
643VOID\r
644DelinkMemoryBlock (\r
645 IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
646 IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader\r
647 )\r
648/*++\r
649\r
650Routine Description:\r
651\r
652 Delink Memory Block\r
653\r
654Arguments:\r
655\r
656 FirstMemoryHeader - MEMORY_MANAGE_HEADER\r
657 NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER\r
658\r
659Returns:\r
660\r
661 VOID\r
662\r
663--*/\r
664{\r
665 MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
666\r
667 if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {\r
668 return ;\r
669 }\r
670\r
671 for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
672\r
673 if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {\r
674 //\r
675 // Link the before and after\r
676 //\r
677 TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;\r
678 break;\r
679 }\r
680 }\r
681}\r
682\r
683EFI_STATUS\r
684InitialMemoryManagement (\r
685 IN USB2_HC_DEV *HcDev\r
686 )\r
687/*++\r
688\r
689Routine Description:\r
690\r
691 Initialize Memory Management\r
692\r
693Arguments:\r
694\r
695 HcDev - USB2_HC_DEV\r
696\r
697Returns:\r
698\r
699 EFI_SUCCESS Success\r
700 EFI_DEVICE_ERROR Fail\r
701 \r
702--*/\r
703{\r
704 EFI_STATUS Status;\r
705 MEMORY_MANAGE_HEADER *MemoryHeader;\r
706 UINTN MemPages;\r
707\r
708 MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
709 Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);\r
710 if (EFI_ERROR (Status)) {\r
711 Status = EFI_OUT_OF_RESOURCES;\r
712 goto exit;\r
713 }\r
714\r
715 HcDev->MemoryHeader = MemoryHeader;\r
716\r
717exit:\r
718 return Status;\r
719}\r
720\r
721EFI_STATUS\r
722DeinitialMemoryManagement (\r
723 IN USB2_HC_DEV *HcDev\r
724 )\r
725/*++\r
726\r
727Routine Description:\r
728\r
729 Deinitialize Memory Management\r
730\r
731Arguments:\r
732\r
733 HcDev - USB2_HC_DEV\r
734\r
735Returns:\r
736\r
737 EFI_SUCCESS Success\r
738 EFI_DEVICE_ERROR Fail\r
739 \r
740--*/\r
741{\r
742 MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
743\r
744 for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
745\r
746 DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);\r
747 //\r
748 // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
749 // the TempHeaderPtr is pointing to nonsense content.\r
750 //\r
751 FreeMemoryHeader (HcDev, TempHeaderPtr);\r
752 //\r
753 // reset the TempHeaderPtr,continue free another memory block.\r
754 //\r
755 TempHeaderPtr = HcDev->MemoryHeader->Next;\r
756 }\r
757\r
758 FreeMemoryHeader (HcDev, HcDev->MemoryHeader);\r
759\r
760 return EFI_SUCCESS;\r
761}\r