1 /** @file
2 OHCI transfer scheduling routines.
3
4 Copyright (c) 2013-2015 Intel Corporation.
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include "OhcPeim.h"
18
19 /**
20
21 Convert Error code from OHCI format to EFI format
22
23 @Param ErrorCode ErrorCode in OHCI format
24
25 @retval ErrorCode in EFI format
26
27 **/
28 UINT32
ConvertErrorCode(IN UINT32 ErrorCode)29 ConvertErrorCode (
30 IN UINT32 ErrorCode
31 )
32 {
33 UINT32 TransferResult;
34
35 switch (ErrorCode) {
36 case TD_NO_ERROR:
37 TransferResult = EFI_USB_NOERROR;
38 break;
39
40 case TD_TOBE_PROCESSED:
41 case TD_TOBE_PROCESSED_2:
42 TransferResult = EFI_USB_ERR_NOTEXECUTE;
43 break;
44
45 case TD_DEVICE_STALL:
46 TransferResult = EFI_USB_ERR_STALL;
47 break;
48
49 case TD_BUFFER_OVERRUN:
50 case TD_BUFFER_UNDERRUN:
51 TransferResult = EFI_USB_ERR_BUFFER;
52 break;
53
54 case TD_CRC_ERROR:
55 TransferResult = EFI_USB_ERR_CRC;
56 break;
57
58 case TD_NO_RESPONSE:
59 TransferResult = EFI_USB_ERR_TIMEOUT;
60 break;
61
62 case TD_BITSTUFFING_ERROR:
63 TransferResult = EFI_USB_ERR_BITSTUFF;
64 break;
65
66 default:
67 TransferResult = EFI_USB_ERR_SYSTEM;
68 }
69
70 return TransferResult;
71 }
72
73
74 /**
75
76 Check TDs Results
77
78 @Param Ohc UHC private data
79 @Param Td TD_DESCRIPTOR
80 @Param Result Result to return
81
82 @retval TRUE means OK
83 @retval FLASE means Error or Short packet
84
85 **/
86 BOOLEAN
OhciCheckTDsResults(IN USB_OHCI_HC_DEV * Ohc,IN TD_DESCRIPTOR * Td,OUT UINT32 * Result)87 OhciCheckTDsResults (
88 IN USB_OHCI_HC_DEV *Ohc,
89 IN TD_DESCRIPTOR *Td,
90 OUT UINT32 *Result
91 )
92 {
93 UINT32 TdCompletionCode;
94
95 *Result = EFI_USB_NOERROR;
96
97 while (Td) {
98 TdCompletionCode = Td->Word0.ConditionCode;
99
100 *Result |= ConvertErrorCode(TdCompletionCode);
101 //
102 // if any error encountered, stop processing the left TDs.
103 //
104 if (*Result) {
105 return FALSE;
106 }
107
108 Td = Td->NextTDPointer;
109 }
110 return TRUE;
111
112 }
113
114
115 /**
116
117 Check the task status on an ED
118
119 @Param Ed Pointer to the ED task that TD hooked on
120 @Param HeadTd TD header for current transaction
121
122 @retval Task Status Code
123
124 **/
125
126 UINT32
CheckEDStatus(IN ED_DESCRIPTOR * Ed,IN TD_DESCRIPTOR * HeadTd)127 CheckEDStatus (
128 IN ED_DESCRIPTOR *Ed,
129 IN TD_DESCRIPTOR *HeadTd
130 )
131 {
132 while(HeadTd != NULL) {
133 if (HeadTd->Word0.ConditionCode != 0) {
134 return HeadTd->Word0.ConditionCode;
135 }
136 HeadTd = HeadTd->NextTDPointer;
137 }
138
139 if (OhciGetEDField (Ed, ED_TDHEAD_PTR) != OhciGetEDField (Ed, ED_TDTAIL_PTR)) {
140 return TD_TOBE_PROCESSED;
141 }
142
143 return TD_NO_ERROR;
144 }
145
146 /**
147
148 Check the task status
149
150 @Param Ohc UHC private data
151 @Param ListType Pipe type
152 @Param Ed Pointer to the ED task hooked on
153 @Param HeadTd Head of TD corresponding to the task
154 @Param ErrorCode return the ErrorCode
155
156 @retval EFI_SUCCESS Task done
157 @retval EFI_NOT_READY Task on processing
158 @retval EFI_DEVICE_ERROR Some error occured
159
160 **/
161 EFI_STATUS
CheckIfDone(IN USB_OHCI_HC_DEV * Ohc,IN DESCRIPTOR_LIST_TYPE ListType,IN ED_DESCRIPTOR * Ed,IN TD_DESCRIPTOR * HeadTd,OUT UINT32 * ErrorCode)162 CheckIfDone (
163 IN USB_OHCI_HC_DEV *Ohc,
164 IN DESCRIPTOR_LIST_TYPE ListType,
165 IN ED_DESCRIPTOR *Ed,
166 IN TD_DESCRIPTOR *HeadTd,
167 OUT UINT32 *ErrorCode
168 )
169 {
170 *ErrorCode = TD_TOBE_PROCESSED;
171
172 switch (ListType) {
173 case CONTROL_LIST:
174 if (OhciGetHcCommandStatus (Ohc, CONTROL_LIST_FILLED) != 0) {
175 return EFI_NOT_READY;
176 }
177 break;
178
179 case BULK_LIST:
180 if (OhciGetHcCommandStatus (Ohc, BULK_LIST_FILLED) != 0) {
181 return EFI_NOT_READY;
182 }
183 break;
184
185 default:
186 break;
187 }
188
189 *ErrorCode = CheckEDStatus (Ed, HeadTd);
190
191
192 if (*ErrorCode == TD_NO_ERROR) {
193 return EFI_SUCCESS;
194 } else if (*ErrorCode == TD_TOBE_PROCESSED) {
195 return EFI_NOT_READY;
196 } else {
197 return EFI_DEVICE_ERROR;
198 }
199 }
200
201
202 /**
203
204 Convert TD condition code to Efi Status
205
206 @Param ConditionCode Condition code to convert
207
208 @retval EFI_SUCCESS No error occured
209 @retval EFI_NOT_READY TD still on processing
210 @retval EFI_DEVICE_ERROR Error occured in processing TD
211
212 **/
213
214 EFI_STATUS
OhciTDConditionCodeToStatus(IN UINT32 ConditionCode)215 OhciTDConditionCodeToStatus (
216 IN UINT32 ConditionCode
217 )
218 {
219 if (ConditionCode == TD_NO_ERROR) {
220 return EFI_SUCCESS;
221 }
222
223 if (ConditionCode == TD_TOBE_PROCESSED) {
224 return EFI_NOT_READY;
225 }
226
227 return EFI_DEVICE_ERROR;
228 }
229
230