2 This file contains URB request, each request is warpped in a
3 URB (Usb Request Block).
5 Copyright (c) 2013-2015 Intel Corporation.
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 @Param Ohc UHC private data
28 @retval TD structure pointer
33 IN USB_OHCI_HC_DEV
*Ohc
38 Td
= UsbHcAllocateMem(Ohc
->MemPool
, sizeof(TD_DESCRIPTOR
));
40 DEBUG ((EFI_D_INFO
, "STV allocate TD fail !\r\n"));
43 Td
->CurrBufferPointer
= 0;
45 Td
->BufferEndPointer
= 0;
46 Td
->NextTDPointer
= 0;
56 @Param Ohc UHC private data
57 @Param Td Pointer to a TD to free
59 @retval EFI_SUCCESS TD freed
64 IN USB_OHCI_HC_DEV
*Ohc
,
71 UsbHcFreeMem(Ohc
->MemPool
, Td
, sizeof(TD_DESCRIPTOR
));
81 @Param Ohc Device private data
83 @retval ED descriptor pointer
92 Ed
= UsbHcAllocateMem(Ohc
->MemPool
, sizeof (ED_DESCRIPTOR
));
94 DEBUG ((EFI_D_INFO
, "STV allocate ED fail !\r\n"));
98 Ed
->TdTailPointer
= 0;
99 Ed
->Word2
.TdHeadPointer
= 0;
109 @Param Ohc UHC private data
110 @Param Ed Pointer to a ED to free
112 @retval EFI_SUCCESS ED freed
118 IN USB_OHCI_HC_DEV
*Ohc
,
125 UsbHcFreeMem(Ohc
->MemPool
, Ed
, sizeof(ED_DESCRIPTOR
));
134 @Param Ohc Device private data
135 @Param Ed Pointer to a ED to free
137 @retval EFI_SUCCESS ED freed
141 OhciFreeAllTDFromED (
142 IN USB_OHCI_HC_DEV
*Ohc
,
146 TD_DESCRIPTOR
*HeadTd
;
147 TD_DESCRIPTOR
*TailTd
;
149 TD_DESCRIPTOR
*TempTd
;
155 HeadTd
= TD_PTR (Ed
->Word2
.TdHeadPointer
);
156 TailTd
= (TD_DESCRIPTOR
*)(UINTN
)(Ed
->TdTailPointer
);
159 while (Td
!= TailTd
) {
161 Td
= (TD_DESCRIPTOR
*)(UINTN
)(Td
->NextTDPointer
);
162 OhciFreeTD (Ohc
, TempTd
);
170 Find a working ED match the requirement
172 @Param EdHead Head of the ED list
173 @Param DeviceAddress Device address to search
174 @Param EndPointNum End point num to search
175 @Param EdDir ED Direction to search
177 @retval ED descriptor searched
183 IN ED_DESCRIPTOR
*EdHead
,
184 IN UINT8 DeviceAddress
,
185 IN UINT8 EndPointNum
,
191 for (Ed
= EdHead
; Ed
!= NULL
; Ed
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
)) {
192 if (Ed
->Word2
.Halted
== 0 && Ed
->Word0
.Skip
== 0 &&
193 Ed
->Word0
.FunctionAddress
== DeviceAddress
&& Ed
->Word0
.EndPointNum
== EndPointNum
&&
194 Ed
->Word0
.Direction
== EdDir
) {
205 Initialize interrupt list.
207 @Param Ohc Device private data
209 @retval EFI_SUCCESS Initialization done
213 OhciInitializeInterruptList (
217 static UINT32 Leaf
[32] = {0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17,
218 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31};
219 UINT32
*HccaInterruptTable
;
223 ED_DESCRIPTOR
*NewEd
;
225 HccaInterruptTable
= Ohc
->HccaMemoryBlock
->HccaInterruptTable
;
227 for (Index
= 0; Index
< 32; Index
++) {
228 NewEd
= OhciCreateED (Ohc
);
230 return EFI_OUT_OF_RESOURCES
;
232 HccaInterruptTable
[Index
] = (UINT32
)(UINTN
)NewEd
;
235 for (Index
= 0; Index
< 32; Index
++) {
236 Ohc
->IntervalList
[0][Index
] = (ED_DESCRIPTOR
*)(UINTN
)HccaInterruptTable
[Leaf
[Index
]];
240 for (Level
= 1; Level
<= 5; Level
++) {
243 for (Index
= 0; Index
< Count
; Index
++) {
244 Ohc
->IntervalList
[Level
][Index
] = OhciCreateED (Ohc
);
245 if (HccaInterruptTable
[Index
] == 0) {
246 return EFI_OUT_OF_RESOURCES
;
248 Ohc
->IntervalList
[Level
- 1][Index
* 2 ]->NextED
= (UINT32
)(UINTN
)Ohc
->IntervalList
[Level
][Index
];
249 Ohc
->IntervalList
[Level
- 1][Index
* 2 + 1]->NextED
= (UINT32
)(UINTN
)Ohc
->IntervalList
[Level
][Index
];
260 @Param Ed Ed to be attached
261 @Param NewEd Ed to attach
263 @retval EFI_SUCCESS NewEd attached to Ed
264 @retval EFI_INVALID_PARAMETER Ed is NULL
269 IN ED_DESCRIPTOR
*Ed
,
270 IN ED_DESCRIPTOR
*NewEd
276 return EFI_INVALID_PARAMETER
;
279 if (Ed
->NextED
== 0){
280 Ed
->NextED
= (UINT32
)(UINTN
)NewEd
;
282 Temp
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
283 Ed
->NextED
= (UINT32
)(UINTN
)NewEd
;
284 NewEd
->NextED
= (UINT32
)(UINTN
)Temp
;
293 Count ED number on a ED chain
295 @Param Ed Head of the ED chain
297 @retval ED number on the chain
311 Ed
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
320 Find the minimal burn ED list on a specific depth level
322 @Param Ohc Device private data
323 @Param Depth Depth level
325 @retval ED list found
330 OhciFindMinInterruptEDList (
331 IN USB_OHCI_HC_DEV
*Ohc
,
337 ED_DESCRIPTOR
*TempEd
;
338 ED_DESCRIPTOR
*HeadEd
;
345 MinEdNum
= 0xFFFFFFFF;
347 for (Index
= 0; Index
< (UINTN
)(32 >> Depth
); Index
++) {
348 HeadEd
= Ohc
->IntervalList
[Depth
][Index
];
349 EdNum
= CountEdNum (HeadEd
);
350 if (EdNum
< MinEdNum
) {
356 ASSERT (TempEd
!= NULL
);
364 Attach an ED to an ED list
366 @Param OHC UHC private data
367 @Param ListType Type of the ED list
368 @Param Ed ED to attach
369 @Param EdList ED list to be attached
371 @retval EFI_SUCCESS ED attached to ED list
376 IN USB_OHCI_HC_DEV
*Ohc
,
377 IN DESCRIPTOR_LIST_TYPE ListType
,
378 IN ED_DESCRIPTOR
*Ed
,
379 IN ED_DESCRIPTOR
*EdList
382 ED_DESCRIPTOR
*HeadEd
;
387 HeadEd
= (ED_DESCRIPTOR
*) OhciGetMemoryPointer (Ohc
, HC_CONTROL_HEAD
);
388 if (HeadEd
== NULL
) {
389 OhciSetMemoryPointer (Ohc
, HC_CONTROL_HEAD
, Ed
);
392 OhciAttachED (HeadEd
, Ed
);
397 HeadEd
= (ED_DESCRIPTOR
*) OhciGetMemoryPointer (Ohc
, HC_BULK_HEAD
);
398 if (HeadEd
== NULL
) {
399 OhciSetMemoryPointer (Ohc
, HC_BULK_HEAD
, Ed
);
402 OhciAttachED (HeadEd
, Ed
);
407 OhciAttachED (EdList
, Ed
);
419 Remove interrupt EDs that match requirement
421 @Param Ohc UHC private data
422 @Param IntEd The address of Interrupt endpoint
424 @retval EFI_SUCCESS EDs match requirement removed
429 OhciFreeInterruptEdByEd (
430 IN USB_OHCI_HC_DEV
*Ohc
,
431 IN ED_DESCRIPTOR
*IntEd
435 ED_DESCRIPTOR
*TempEd
;
441 for (Index
= 0; Index
< 32; Index
++) {
442 Ed
= (ED_DESCRIPTOR
*)(UINTN
)Ohc
->HccaMemoryBlock
->HccaInterruptTable
[Index
];
446 while (Ed
->NextED
!= 0) {
447 if (Ed
->NextED
== (UINT32
)(UINTN
)IntEd
) {
448 TempEd
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
449 Ed
->NextED
= TempEd
->NextED
;
450 OhciFreeED (Ohc
, TempEd
);
452 Ed
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
461 Remove interrupt EDs that match requirement
463 @Param Ohc UHC private data
464 @Param FunctionAddress Requirement on function address
465 @Param EndPointNum Requirement on end point number
467 @retval EFI_SUCCESS EDs match requirement removed
471 OhciFreeInterruptEdByAddr (
472 IN USB_OHCI_HC_DEV
*Ohc
,
473 IN UINT8 FunctionAddress
,
478 ED_DESCRIPTOR
*TempEd
;
481 for (Index
= 0; Index
< 32; Index
++) {
482 Ed
= (ED_DESCRIPTOR
*)(UINTN
)Ohc
->HccaMemoryBlock
->HccaInterruptTable
[Index
];
487 while (Ed
->NextED
!= 0) {
488 TempEd
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
489 if (TempEd
->Word0
.FunctionAddress
== FunctionAddress
&&
490 TempEd
->Word0
.EndPointNum
== EndPointNum
) {
491 Ed
->NextED
= TempEd
->NextED
;
492 OhciFreeED (Ohc
, TempEd
);
494 Ed
= (ED_DESCRIPTOR
*)(UINTN
)(Ed
->NextED
);
505 Link Td2 to the end of Td1
507 @Param Td1 TD to be linked
508 @Param Td2 TD to link
510 @retval EFI_SUCCESS TD successfully linked
511 @retval EFI_INVALID_PARAMETER Td1 is NULL
516 IN TD_DESCRIPTOR
*Td1
,
517 IN TD_DESCRIPTOR
*Td2
520 TD_DESCRIPTOR
*TempTd
;
523 return EFI_INVALID_PARAMETER
;
531 while (TempTd
->NextTD
!= 0) {
532 TempTd
= (TD_DESCRIPTOR
*)(UINTN
)(TempTd
->NextTD
);
535 TempTd
->NextTD
= (UINT32
)(UINTN
)Td2
;
536 TempTd
->NextTDPointer
= (UINT32
)(UINTN
)Td2
;
546 @Param Ed ED which TD list attach on
547 @Param HeadTd Head of the TD list to attach
549 @retval EFI_SUCCESS TD list attached on the ED
553 OhciAttachTDListToED (
554 IN ED_DESCRIPTOR
*Ed
,
555 IN TD_DESCRIPTOR
*HeadTd
558 TD_DESCRIPTOR
*TempTd
;
560 TempTd
= TD_PTR (Ed
->Word2
.TdHeadPointer
);
562 if (TempTd
!= NULL
) {
563 while (TempTd
->NextTD
!= 0) {
564 TempTd
= (TD_DESCRIPTOR
*)(UINTN
)(TempTd
->NextTD
);
566 TempTd
->NextTD
= (UINT32
)(UINTN
)HeadTd
;
567 TempTd
->NextTDPointer
= (UINT32
)(UINTN
)HeadTd
;
569 Ed
->Word2
.TdHeadPointer
= RIGHT_SHIFT_4 ((UINT32
)(UINTN
)HeadTd
);
578 Set value to ED specific field
580 @Param Ed ED to be set
581 @Param Field Field to be set
582 @Param Value Value to set
584 @retval EFI_SUCCESS Value set
589 IN ED_DESCRIPTOR
*Ed
,
594 if (Field
& ED_FUNC_ADD
) {
595 Ed
->Word0
.FunctionAddress
= Value
;
597 if (Field
& ED_ENDPT_NUM
) {
598 Ed
->Word0
.EndPointNum
= Value
;
600 if (Field
& ED_DIR
) {
601 Ed
->Word0
.Direction
= Value
;
603 if (Field
& ED_SPEED
) {
604 Ed
->Word0
.Speed
= Value
;
606 if (Field
& ED_SKIP
) {
607 Ed
->Word0
.Skip
= Value
;
609 if (Field
& ED_FORMAT
) {
610 Ed
->Word0
.Format
= Value
;
612 if (Field
& ED_MAX_PACKET
) {
613 Ed
->Word0
.MaxPacketSize
= Value
;
615 if (Field
& ED_PDATA
) {
616 Ed
->Word0
.FreeSpace
= Value
;
618 if (Field
& ED_ZERO
) {
619 Ed
->Word2
.Zero
= Value
;
621 if (Field
& ED_TDTAIL_PTR
) {
622 Ed
->TdTailPointer
= Value
;
625 if (Field
& ED_HALTED
) {
626 Ed
->Word2
.Halted
= Value
;
628 if (Field
& ED_DTTOGGLE
) {
629 Ed
->Word2
.ToggleCarry
= Value
;
631 if (Field
& ED_TDHEAD_PTR
) {
632 Ed
->Word2
.TdHeadPointer
= RIGHT_SHIFT_4 (Value
);
635 if (Field
& ED_NEXT_EDPTR
) {
644 Get value from an ED's specific field
647 @Param Field Field to get value from
649 @retval Value of the field
654 IN ED_DESCRIPTOR
*Ed
,
660 return Ed
->Word0
.FunctionAddress
;
663 return Ed
->Word0
.EndPointNum
;
666 return Ed
->Word0
.Direction
;
669 return Ed
->Word0
.Speed
;
672 return Ed
->Word0
.Skip
;
675 return Ed
->Word0
.Format
;
678 return Ed
->Word0
.MaxPacketSize
;
682 return Ed
->TdTailPointer
;
686 return Ed
->Word2
.Halted
;
690 return Ed
->Word2
.ToggleCarry
;
694 return Ed
->Word2
.TdHeadPointer
<< 4;
711 Set value to TD specific field
713 @Param Td TD to be set
714 @Param Field Field to be set
715 @Param Value Value to set
717 @retval EFI_SUCCESS Value set
722 IN TD_DESCRIPTOR
*Td
,
727 if (Field
& TD_PDATA
) {
728 Td
->Word0
.Reserved
= Value
;
730 if (Field
& TD_BUFFER_ROUND
) {
731 Td
->Word0
.BufferRounding
= Value
;
733 if (Field
& TD_DIR_PID
) {
734 Td
->Word0
.DirPID
= Value
;
736 if (Field
& TD_DELAY_INT
) {
737 Td
->Word0
.DelayInterrupt
= Value
;
739 if (Field
& TD_DT_TOGGLE
) {
740 Td
->Word0
.DataToggle
= Value
| 0x2;
742 if (Field
& TD_ERROR_CNT
) {
743 Td
->Word0
.ErrorCount
= Value
;
745 if (Field
& TD_COND_CODE
) {
746 Td
->Word0
.ConditionCode
= Value
;
749 if (Field
& TD_CURR_BUFFER_PTR
) {
750 Td
->CurrBufferPointer
= Value
;
754 if (Field
& TD_NEXT_PTR
) {
758 if (Field
& TD_BUFFER_END_PTR
) {
759 Td
->BufferEndPointer
= Value
;
768 Get value from ED specific field
771 @Param Field Field to get value from
773 @retval Value of the field
779 IN TD_DESCRIPTOR
*Td
,
784 case TD_BUFFER_ROUND
:
785 return Td
->Word0
.BufferRounding
;
788 return Td
->Word0
.DirPID
;
791 return Td
->Word0
.DelayInterrupt
;
794 return Td
->Word0
.DataToggle
;
797 return Td
->Word0
.ErrorCount
;
800 return Td
->Word0
.ConditionCode
;
802 case TD_CURR_BUFFER_PTR
:
803 return Td
->CurrBufferPointer
;
810 case TD_BUFFER_END_PTR
:
811 return Td
->BufferEndPointer
;
823 Free the Ed,Td,buffer that were created during transferring
825 @Param Ohc Device private data
829 OhciFreeDynamicIntMemory(
830 IN USB_OHCI_HC_DEV
*Ohc
833 INTERRUPT_CONTEXT_ENTRY
*Entry
;
835 while (Ohc
->InterruptContextList
!= NULL
) {
836 Entry
= Ohc
->InterruptContextList
;
837 Ohc
->InterruptContextList
= Ohc
->InterruptContextList
->NextEntry
;
838 OhciFreeInterruptEdByEd (Ohc
, Entry
->Ed
);
839 OhciFreeInterruptContextEntry (Ohc
, Entry
);
845 Free the Ed that were initilized during driver was starting,
846 those memory were used as interrupt ED head
848 @Param Ohc Device private data
853 OhciFreeFixedIntMemory (
854 IN USB_OHCI_HC_DEV
*Ohc
857 static UINT32 Leaf
[] = {32,16,8,4,2,1};
861 for (Level
= 0; Level
< 6; Level
++) {
862 for (Index
= 0; Index
< Leaf
[Level
]; Index
++) {
863 if (Ohc
->IntervalList
[Level
][Index
] != NULL
) {
864 UsbHcFreeMem(Ohc
->MemPool
, Ohc
->IntervalList
[Level
][Index
], sizeof(ED_DESCRIPTOR
));
871 Release all OHCI used memory when OHCI going to quit
873 @Param Ohc Device private data
875 @retval EFI_SUCCESS Memory released
880 OhciFreeIntTransferMemory (
881 IN USB_OHCI_HC_DEV
*Ohc
885 // Free the Ed,Td,buffer that were created during transferring
887 OhciFreeDynamicIntMemory (Ohc
);
889 // Free the Ed that were initilized during driver was starting
891 OhciFreeFixedIntMemory (Ohc
);