]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c
QuarkSocPkg: Add new package for Quark SoC X1000
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Usb / Ohci / Dxe / OhciUrb.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2This file contains URB request, each request is warpped in a\r
3URB (Usb Request Block).\r
4\r
5Copyright (c) 2013-2015 Intel Corporation.\r
6\r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17\r
18\r
19#include "Ohci.h"\r
20\r
21\r
22/**\r
23\r
24 Create a TD\r
25\r
26 @Param Ohc UHC private data\r
27\r
28 @retval TD structure pointer\r
29\r
30**/\r
31TD_DESCRIPTOR *\r
32OhciCreateTD (\r
33 IN USB_OHCI_HC_DEV *Ohc\r
34 )\r
35{\r
36 TD_DESCRIPTOR *Td;\r
37\r
38 Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));\r
39 if (Td == NULL) {\r
40 DEBUG ((EFI_D_INFO, "STV allocate TD fail !\r\n"));\r
41 return NULL;\r
42 }\r
43 Td->CurrBufferPointer = 0;\r
44 Td->NextTD = 0;\r
45 Td->BufferEndPointer = 0;\r
46 Td->NextTDPointer = 0;\r
47\r
48 return Td;\r
49}\r
50\r
51\r
52/**\r
53\r
54 Free a TD\r
55\r
56 @Param Ohc UHC private data\r
57 @Param Td Pointer to a TD to free\r
58\r
59 @retval EFI_SUCCESS TD freed\r
60\r
61**/\r
62EFI_STATUS\r
63OhciFreeTD (\r
64 IN USB_OHCI_HC_DEV *Ohc,\r
65 IN TD_DESCRIPTOR *Td\r
66 )\r
67{\r
68 if (Td == NULL) {\r
69 return EFI_SUCCESS;\r
70 }\r
71 UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));\r
72\r
73 return EFI_SUCCESS;\r
74}\r
75\r
76\r
77/**\r
78\r
79 Create a ED\r
80\r
81 @Param Ohc Device private data\r
82\r
83 @retval ED descriptor pointer\r
84\r
85**/\r
86ED_DESCRIPTOR *\r
87OhciCreateED (\r
88 USB_OHCI_HC_DEV *Ohc\r
89 )\r
90{\r
91 ED_DESCRIPTOR *Ed;\r
92 Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));\r
93 if (Ed == NULL) {\r
94 DEBUG ((EFI_D_INFO, "STV allocate ED fail !\r\n"));\r
95 return NULL;\r
96 }\r
97 Ed->Word0.Skip = 1;\r
98 Ed->TdTailPointer = 0;\r
99 Ed->Word2.TdHeadPointer = 0;\r
100 Ed->NextED = 0;\r
101\r
102 return Ed;\r
103}\r
104\r
105/**\r
106\r
107 Free a ED\r
108\r
109 @Param Ohc UHC private data\r
110 @Param Ed Pointer to a ED to free\r
111\r
112 @retval EFI_SUCCESS ED freed\r
113\r
114**/\r
115\r
116EFI_STATUS\r
117OhciFreeED (\r
118 IN USB_OHCI_HC_DEV *Ohc,\r
119 IN ED_DESCRIPTOR *Ed\r
120 )\r
121{\r
122 if (Ed == NULL) {\r
123 return EFI_SUCCESS;\r
124 }\r
125 UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));\r
126\r
127 return EFI_SUCCESS;\r
128}\r
129\r
130/**\r
131\r
132 Free ED\r
133\r
134 @Param Ohc Device private data\r
135 @Param Ed Pointer to a ED to free\r
136\r
137 @retval EFI_SUCCESS ED freed\r
138\r
139**/\r
140EFI_STATUS\r
141OhciFreeAllTDFromED (\r
142 IN USB_OHCI_HC_DEV *Ohc,\r
143 IN ED_DESCRIPTOR *Ed\r
144 )\r
145{\r
146 TD_DESCRIPTOR *HeadTd;\r
147 TD_DESCRIPTOR *TailTd;\r
148 TD_DESCRIPTOR *Td;\r
149 TD_DESCRIPTOR *TempTd;\r
150\r
151 if (Ed == NULL) {\r
152 return EFI_SUCCESS;\r
153 }\r
154\r
155 HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
156 TailTd = (TD_DESCRIPTOR *)(UINTN)(Ed->TdTailPointer);\r
157\r
158 Td = HeadTd;\r
159 while (Td != TailTd) {\r
160 TempTd = Td;\r
161 Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);\r
162 OhciFreeTD (Ohc, TempTd);\r
163 }\r
164\r
165 return EFI_SUCCESS;\r
166}\r
167\r
168/**\r
169\r
170 Find a working ED match the requirement\r
171\r
172 @Param EdHead Head of the ED list\r
173 @Param DeviceAddress Device address to search\r
174 @Param EndPointNum End point num to search\r
175 @Param EdDir ED Direction to search\r
176\r
177 @retval ED descriptor searched\r
178\r
179**/\r
180\r
181ED_DESCRIPTOR *\r
182OhciFindWorkingEd (\r
183 IN ED_DESCRIPTOR *EdHead,\r
184 IN UINT8 DeviceAddress,\r
185 IN UINT8 EndPointNum,\r
186 IN UINT8 EdDir\r
187 )\r
188{\r
189 ED_DESCRIPTOR *Ed;\r
190\r
191 for (Ed = EdHead; Ed != NULL; Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED)) {\r
192 if (Ed->Word2.Halted == 0 && Ed->Word0.Skip == 0 &&\r
193 Ed->Word0.FunctionAddress == DeviceAddress && Ed->Word0.EndPointNum == EndPointNum &&\r
194 Ed->Word0.Direction == EdDir) {\r
195 break;\r
196 }\r
197 }\r
198\r
199 return Ed;\r
200}\r
201\r
202\r
203/**\r
204\r
205 Initialize interrupt list.\r
206\r
207 @Param Ohc Device private data\r
208\r
209 @retval EFI_SUCCESS Initialization done\r
210\r
211**/\r
212EFI_STATUS\r
213OhciInitializeInterruptList (\r
214 USB_OHCI_HC_DEV *Ohc\r
215 )\r
216{\r
217 static UINT32 Leaf[32] = {0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17,\r
218 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31};\r
219 UINT32 *HccaInterruptTable;\r
220 UINTN Index;\r
221 UINTN Level;\r
222 UINTN Count;\r
223 ED_DESCRIPTOR *NewEd;\r
224\r
225 HccaInterruptTable = Ohc->HccaMemoryBlock->HccaInterruptTable;\r
226\r
227 for (Index = 0; Index < 32; Index++) {\r
228 NewEd = OhciCreateED (Ohc);\r
229 if (NewEd == NULL) {\r
230 return EFI_OUT_OF_RESOURCES;\r
231 }\r
232 HccaInterruptTable[Index] = (UINT32)(UINTN)NewEd;\r
233 }\r
234\r
235 for (Index = 0; Index < 32; Index++) {\r
236 Ohc->IntervalList[0][Index] = (ED_DESCRIPTOR *)(UINTN)HccaInterruptTable[Leaf[Index]];\r
237 }\r
238\r
239 Count = 32;\r
240 for (Level = 1; Level <= 5; Level++) {\r
241 Count = Count >> 1;\r
242\r
243 for (Index = 0; Index < Count; Index++) {\r
244 Ohc->IntervalList[Level][Index] = OhciCreateED (Ohc);\r
245 if (HccaInterruptTable[Index] == 0) {\r
246 return EFI_OUT_OF_RESOURCES;\r
247 }\r
248 Ohc->IntervalList[Level - 1][Index * 2 ]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];\r
249 Ohc->IntervalList[Level - 1][Index * 2 + 1]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];\r
250 }\r
251 }\r
252\r
253 return EFI_SUCCESS;\r
254}\r
255\r
256/**\r
257\r
258 Attach an ED\r
259\r
260 @Param Ed Ed to be attached\r
261 @Param NewEd Ed to attach\r
262\r
263 @retval EFI_SUCCESS NewEd attached to Ed\r
264 @retval EFI_INVALID_PARAMETER Ed is NULL\r
265\r
266**/\r
267EFI_STATUS\r
268OhciAttachED (\r
269 IN ED_DESCRIPTOR *Ed,\r
270 IN ED_DESCRIPTOR *NewEd\r
271 )\r
272{\r
273 ED_DESCRIPTOR *Temp;\r
274\r
275 if (Ed == NULL) {\r
276 return EFI_INVALID_PARAMETER;\r
277 }\r
278\r
279 if (Ed->NextED == 0){\r
280 Ed->NextED = (UINT32)(UINTN)NewEd;\r
281 } else {\r
282 Temp = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
283 Ed->NextED = (UINT32)(UINTN)NewEd;\r
284 NewEd->NextED = (UINT32)(UINTN)Temp;\r
285 }\r
286\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290\r
291/**\r
292\r
293 Count ED number on a ED chain\r
294\r
295 @Param Ed Head of the ED chain\r
296\r
297 @retval ED number on the chain\r
298\r
299**/\r
300\r
301UINTN\r
302CountEdNum (\r
303 IN ED_DESCRIPTOR *Ed\r
304 )\r
305{\r
306 UINTN Count;\r
307\r
308 Count = 0;\r
309\r
310 while (Ed) {\r
311 Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
312 Count++;\r
313 }\r
314\r
315 return Count;\r
316}\r
317\r
318/**\r
319\r
320 Find the minimal burn ED list on a specific depth level\r
321\r
322 @Param Ohc Device private data\r
323 @Param Depth Depth level\r
324\r
325 @retval ED list found\r
326\r
327**/\r
328\r
329ED_DESCRIPTOR *\r
330OhciFindMinInterruptEDList (\r
331 IN USB_OHCI_HC_DEV *Ohc,\r
332 IN UINT32 Depth\r
333 )\r
334{\r
335 UINTN EdNum;\r
336 UINTN MinEdNum;\r
337 ED_DESCRIPTOR *TempEd;\r
338 ED_DESCRIPTOR *HeadEd;\r
339 UINTN Index;\r
340\r
341 if (Depth > 5) {\r
342 return NULL;\r
343 }\r
344\r
345 MinEdNum = 0xFFFFFFFF;\r
346 TempEd = NULL;\r
347 for (Index = 0; Index < (UINTN)(32 >> Depth); Index++) {\r
348 HeadEd = Ohc->IntervalList[Depth][Index];\r
349 EdNum = CountEdNum (HeadEd);\r
350 if (EdNum < MinEdNum) {\r
351 MinEdNum = EdNum;\r
352 TempEd = HeadEd;\r
353 }\r
354 }\r
355\r
356 ASSERT (TempEd != NULL);\r
357\r
358 return TempEd;\r
359}\r
360\r
361\r
362/**\r
363\r
364 Attach an ED to an ED list\r
365\r
366 @Param OHC UHC private data\r
367 @Param ListType Type of the ED list\r
368 @Param Ed ED to attach\r
369 @Param EdList ED list to be attached\r
370\r
371 @retval EFI_SUCCESS ED attached to ED list\r
372\r
373**/\r
374ED_DESCRIPTOR *\r
375OhciAttachEDToList (\r
376 IN USB_OHCI_HC_DEV *Ohc,\r
377 IN DESCRIPTOR_LIST_TYPE ListType,\r
378 IN ED_DESCRIPTOR *Ed,\r
379 IN ED_DESCRIPTOR *EdList\r
380 )\r
381{\r
382 ED_DESCRIPTOR *HeadEd;\r
383\r
384 HeadEd = NULL;\r
385 switch(ListType) {\r
386 case CONTROL_LIST:\r
387 HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);\r
388 if (HeadEd == NULL) {\r
389 OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);\r
390 HeadEd = Ed;\r
391 } else {\r
392 OhciAttachED (HeadEd, Ed);\r
393 }\r
394 break;\r
395\r
396 case BULK_LIST:\r
397 HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);\r
398 if (HeadEd == NULL) {\r
399 OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);\r
400 HeadEd = Ed;\r
401 } else {\r
402 OhciAttachED (HeadEd, Ed);\r
403 }\r
404 break;\r
405\r
406 case INTERRUPT_LIST:\r
407 OhciAttachED (EdList, Ed);\r
408 break;\r
409\r
410 default:\r
411 ASSERT (FALSE);\r
412 }\r
413\r
414 return HeadEd;\r
415}\r
416\r
417/**\r
418\r
419 Remove interrupt EDs that match requirement\r
420\r
421 @Param Ohc UHC private data\r
422 @Param IntEd The address of Interrupt endpoint\r
423\r
424 @retval EFI_SUCCESS EDs match requirement removed\r
425\r
426**/\r
427\r
428EFI_STATUS\r
429OhciFreeInterruptEdByEd (\r
430 IN USB_OHCI_HC_DEV *Ohc,\r
431 IN ED_DESCRIPTOR *IntEd\r
432 )\r
433{\r
434 ED_DESCRIPTOR *Ed;\r
435 ED_DESCRIPTOR *TempEd;\r
436 UINTN Index;\r
437\r
438 if (IntEd == NULL)\r
439 return EFI_SUCCESS;\r
440\r
441 for (Index = 0; Index < 32; Index++) {\r
442 Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];\r
443 if (Ed == NULL) {\r
444 continue;\r
445 }\r
446 while (Ed->NextED != 0) {\r
447 if (Ed->NextED == (UINT32)(UINTN)IntEd ) {\r
448 TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
449 Ed->NextED = TempEd->NextED;\r
450 OhciFreeED (Ohc, TempEd);\r
451 } else {\r
452 Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
453 }\r
454 }\r
455 }\r
456 return EFI_SUCCESS;\r
457}\r
458\r
459/**\r
460\r
461 Remove interrupt EDs that match requirement\r
462\r
463 @Param Ohc UHC private data\r
464 @Param FunctionAddress Requirement on function address\r
465 @Param EndPointNum Requirement on end point number\r
466\r
467 @retval EFI_SUCCESS EDs match requirement removed\r
468\r
469**/\r
470EFI_STATUS\r
471OhciFreeInterruptEdByAddr (\r
472 IN USB_OHCI_HC_DEV *Ohc,\r
473 IN UINT8 FunctionAddress,\r
474 IN UINT8 EndPointNum\r
475 )\r
476{\r
477 ED_DESCRIPTOR *Ed;\r
478 ED_DESCRIPTOR *TempEd;\r
479 UINTN Index;\r
480\r
481 for (Index = 0; Index < 32; Index++) {\r
482 Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];\r
483 if (Ed == NULL) {\r
484 continue;\r
485 }\r
486\r
487 while (Ed->NextED != 0) {\r
488 TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
489 if (TempEd->Word0.FunctionAddress == FunctionAddress &&\r
490 TempEd->Word0.EndPointNum == EndPointNum ) {\r
491 Ed->NextED = TempEd->NextED;\r
492 OhciFreeED (Ohc, TempEd);\r
493 } else {\r
494 Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);\r
495 }\r
496 }\r
497 }\r
498\r
499 return EFI_SUCCESS;\r
500}\r
501\r
502\r
503/**\r
504\r
505 Link Td2 to the end of Td1\r
506\r
507 @Param Td1 TD to be linked\r
508 @Param Td2 TD to link\r
509\r
510 @retval EFI_SUCCESS TD successfully linked\r
511 @retval EFI_INVALID_PARAMETER Td1 is NULL\r
512\r
513**/\r
514EFI_STATUS\r
515OhciLinkTD (\r
516 IN TD_DESCRIPTOR *Td1,\r
517 IN TD_DESCRIPTOR *Td2\r
518 )\r
519{\r
520 TD_DESCRIPTOR *TempTd;\r
521\r
522 if (Td1 == NULL) {\r
523 return EFI_INVALID_PARAMETER;\r
524 }\r
525\r
526 if (Td1 == Td2) {\r
527 return EFI_SUCCESS;\r
528 }\r
529\r
530 TempTd = Td1;\r
531 while (TempTd->NextTD != 0) {\r
532 TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);\r
533 }\r
534\r
535 TempTd->NextTD = (UINT32)(UINTN)Td2;\r
536 TempTd->NextTDPointer = (UINT32)(UINTN)Td2;\r
537\r
538 return EFI_SUCCESS;\r
539}\r
540\r
541\r
542/**\r
543\r
544 Attach TD list to ED\r
545\r
546 @Param Ed ED which TD list attach on\r
547 @Param HeadTd Head of the TD list to attach\r
548\r
549 @retval EFI_SUCCESS TD list attached on the ED\r
550\r
551**/\r
552EFI_STATUS\r
553OhciAttachTDListToED (\r
554 IN ED_DESCRIPTOR *Ed,\r
555 IN TD_DESCRIPTOR *HeadTd\r
556 )\r
557{\r
558 TD_DESCRIPTOR *TempTd;\r
559\r
560 TempTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
561\r
562 if (TempTd != NULL) {\r
563 while (TempTd->NextTD != 0) {\r
564 TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);\r
565 }\r
566 TempTd->NextTD = (UINT32)(UINTN)HeadTd;\r
567 TempTd->NextTDPointer = (UINT32)(UINTN)HeadTd;\r
568 } else {\r
569 Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32)(UINTN)HeadTd);\r
570 }\r
571\r
572 return EFI_SUCCESS;\r
573}\r
574\r
575\r
576/**\r
577\r
578 Set value to ED specific field\r
579\r
580 @Param Ed ED to be set\r
581 @Param Field Field to be set\r
582 @Param Value Value to set\r
583\r
584 @retval EFI_SUCCESS Value set\r
585\r
586**/\r
587EFI_STATUS\r
588OhciSetEDField (\r
589 IN ED_DESCRIPTOR *Ed,\r
590 IN UINT32 Field,\r
591 IN UINT32 Value\r
592 )\r
593{\r
594 if (Field & ED_FUNC_ADD) {\r
595 Ed->Word0.FunctionAddress = Value;\r
596 }\r
597 if (Field & ED_ENDPT_NUM) {\r
598 Ed->Word0.EndPointNum = Value;\r
599 }\r
600 if (Field & ED_DIR) {\r
601 Ed->Word0.Direction = Value;\r
602 }\r
603 if (Field & ED_SPEED) {\r
604 Ed->Word0.Speed = Value;\r
605 }\r
606 if (Field & ED_SKIP) {\r
607 Ed->Word0.Skip = Value;\r
608 }\r
609 if (Field & ED_FORMAT) {\r
610 Ed->Word0.Format = Value;\r
611 }\r
612 if (Field & ED_MAX_PACKET) {\r
613 Ed->Word0.MaxPacketSize = Value;\r
614 }\r
615 if (Field & ED_PDATA) {\r
616 Ed->Word0.FreeSpace = Value;\r
617 }\r
618 if (Field & ED_ZERO) {\r
619 Ed->Word2.Zero = Value;\r
620 }\r
621 if (Field & ED_TDTAIL_PTR) {\r
622 Ed->TdTailPointer = Value;\r
623 }\r
624\r
625 if (Field & ED_HALTED) {\r
626 Ed->Word2.Halted = Value;\r
627 }\r
628 if (Field & ED_DTTOGGLE) {\r
629 Ed->Word2.ToggleCarry = Value;\r
630 }\r
631 if (Field & ED_TDHEAD_PTR) {\r
632 Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);\r
633 }\r
634\r
635 if (Field & ED_NEXT_EDPTR) {\r
636 Ed->NextED = Value;\r
637 }\r
638\r
639 return EFI_SUCCESS;\r
640}\r
641\r
642/**\r
643\r
644 Get value from an ED's specific field\r
645\r
646 @Param Ed ED pointer\r
647 @Param Field Field to get value from\r
648\r
649 @retval Value of the field\r
650\r
651**/\r
652UINT32\r
653OhciGetEDField (\r
654 IN ED_DESCRIPTOR *Ed,\r
655 IN UINT32 Field\r
656 )\r
657{\r
658 switch (Field) {\r
659 case ED_FUNC_ADD:\r
660 return Ed->Word0.FunctionAddress;\r
661 break;\r
662 case ED_ENDPT_NUM:\r
663 return Ed->Word0.EndPointNum;\r
664 break;\r
665 case ED_DIR:\r
666 return Ed->Word0.Direction;\r
667 break;\r
668 case ED_SPEED:\r
669 return Ed->Word0.Speed;\r
670 break;\r
671 case ED_SKIP:\r
672 return Ed->Word0.Skip;\r
673 break;\r
674 case ED_FORMAT:\r
675 return Ed->Word0.Format;\r
676 break;\r
677 case ED_MAX_PACKET:\r
678 return Ed->Word0.MaxPacketSize;\r
679 break;\r
680\r
681 case ED_TDTAIL_PTR:\r
682 return Ed->TdTailPointer;\r
683 break;\r
684\r
685 case ED_HALTED:\r
686 return Ed->Word2.Halted;\r
687 break;\r
688\r
689 case ED_DTTOGGLE:\r
690 return Ed->Word2.ToggleCarry;\r
691 break;\r
692\r
693 case ED_TDHEAD_PTR:\r
694 return Ed->Word2.TdHeadPointer << 4;\r
695 break;\r
696\r
697 case ED_NEXT_EDPTR:\r
698 return Ed->NextED;\r
699 break;\r
700\r
701 default:\r
702 ASSERT (FALSE);\r
703 }\r
704\r
705 return 0;\r
706}\r
707\r
708\r
709/**\r
710\r
711 Set value to TD specific field\r
712\r
713 @Param Td TD to be set\r
714 @Param Field Field to be set\r
715 @Param Value Value to set\r
716\r
717 @retval EFI_SUCCESS Value set\r
718\r
719**/\r
720EFI_STATUS\r
721OhciSetTDField (\r
722 IN TD_DESCRIPTOR *Td,\r
723 IN UINT32 Field,\r
724 IN UINT32 Value\r
725 )\r
726{\r
727 if (Field & TD_PDATA) {\r
728 Td->Word0.Reserved = Value;\r
729 }\r
730 if (Field & TD_BUFFER_ROUND) {\r
731 Td->Word0.BufferRounding = Value;\r
732 }\r
733 if (Field & TD_DIR_PID) {\r
734 Td->Word0.DirPID = Value;\r
735 }\r
736 if (Field & TD_DELAY_INT) {\r
737 Td->Word0.DelayInterrupt = Value;\r
738 }\r
739 if (Field & TD_DT_TOGGLE) {\r
740 Td->Word0.DataToggle = Value | 0x2;\r
741 }\r
742 if (Field & TD_ERROR_CNT) {\r
743 Td->Word0.ErrorCount = Value;\r
744 }\r
745 if (Field & TD_COND_CODE) {\r
746 Td->Word0.ConditionCode = Value;\r
747 }\r
748\r
749 if (Field & TD_CURR_BUFFER_PTR) {\r
750 Td->CurrBufferPointer = Value;\r
751 }\r
752\r
753\r
754 if (Field & TD_NEXT_PTR) {\r
755 Td->NextTD = Value;\r
756 }\r
757\r
758 if (Field & TD_BUFFER_END_PTR) {\r
759 Td->BufferEndPointer = Value;\r
760 }\r
761\r
762 return EFI_SUCCESS;\r
763}\r
764\r
765\r
766/**\r
767\r
768 Get value from ED specific field\r
769\r
770 @Param Td TD pointer\r
771 @Param Field Field to get value from\r
772\r
773 @retval Value of the field\r
774\r
775**/\r
776\r
777UINT32\r
778OhciGetTDField (\r
779 IN TD_DESCRIPTOR *Td,\r
780 IN UINT32 Field\r
781 )\r
782{\r
783 switch (Field){\r
784 case TD_BUFFER_ROUND:\r
785 return Td->Word0.BufferRounding;\r
786 break;\r
787 case TD_DIR_PID:\r
788 return Td->Word0.DirPID;\r
789 break;\r
790 case TD_DELAY_INT:\r
791 return Td->Word0.DelayInterrupt;\r
792 break;\r
793 case TD_DT_TOGGLE:\r
794 return Td->Word0.DataToggle;\r
795 break;\r
796 case TD_ERROR_CNT:\r
797 return Td->Word0.ErrorCount;\r
798 break;\r
799 case TD_COND_CODE:\r
800 return Td->Word0.ConditionCode;\r
801 break;\r
802 case TD_CURR_BUFFER_PTR:\r
803 return Td->CurrBufferPointer;\r
804 break;\r
805\r
806 case TD_NEXT_PTR:\r
807 return Td->NextTD;\r
808 break;\r
809\r
810 case TD_BUFFER_END_PTR:\r
811 return Td->BufferEndPointer;\r
812 break;\r
813\r
814 default:\r
815 ASSERT (FALSE);\r
816 }\r
817\r
818 return 0;\r
819}\r
820\r
821/**\r
822\r
823 Free the Ed,Td,buffer that were created during transferring\r
824\r
825 @Param Ohc Device private data\r
826**/\r
827\r
828VOID\r
829OhciFreeDynamicIntMemory(\r
830 IN USB_OHCI_HC_DEV *Ohc\r
831 )\r
832{\r
833 INTERRUPT_CONTEXT_ENTRY *Entry;\r
834 if (Ohc != NULL) {\r
835 while (Ohc->InterruptContextList != NULL) {\r
836 Entry = Ohc->InterruptContextList;\r
837 Ohc->InterruptContextList = Ohc->InterruptContextList->NextEntry;\r
838 OhciFreeInterruptEdByEd (Ohc, Entry->Ed);\r
839 OhciFreeInterruptContextEntry (Ohc, Entry);\r
840 }\r
841 }\r
842}\r
843/**\r
844\r
845 Free the Ed that were initilized during driver was starting,\r
846 those memory were used as interrupt ED head\r
847\r
848 @Param Ohc Device private data\r
849\r
850\r
851**/\r
852VOID\r
853OhciFreeFixedIntMemory (\r
854 IN USB_OHCI_HC_DEV *Ohc\r
855 )\r
856{\r
857 static UINT32 Leaf[] = {32,16,8,4,2,1};\r
858 UINTN Index;\r
859 UINTN Level;\r
860\r
861 for (Level = 0; Level < 6; Level++) {\r
862 for (Index = 0; Index < Leaf[Level]; Index++) {\r
863 if (Ohc->IntervalList[Level][Index] != NULL) {\r
864 UsbHcFreeMem(Ohc->MemPool, Ohc->IntervalList[Level][Index], sizeof(ED_DESCRIPTOR));\r
865 }\r
866 }\r
867 }\r
868}\r
869/**\r
870\r
871 Release all OHCI used memory when OHCI going to quit\r
872\r
873 @Param Ohc Device private data\r
874\r
875 @retval EFI_SUCCESS Memory released\r
876\r
877**/\r
878\r
879EFI_STATUS\r
880OhciFreeIntTransferMemory (\r
881 IN USB_OHCI_HC_DEV *Ohc\r
882 )\r
883{\r
884 //\r
885 // Free the Ed,Td,buffer that were created during transferring\r
886 //\r
887 OhciFreeDynamicIntMemory (Ohc);\r
888 //\r
889 // Free the Ed that were initilized during driver was starting\r
890 //\r
891 OhciFreeFixedIntMemory (Ohc);\r
892 return EFI_SUCCESS;\r
893}\r
894\r
895\r