]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c
QuarkSocPkg: Add new package for Quark SoC X1000
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Usb / Ohci / Pei / 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 "OhcPeim.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 return NULL;\r
41 }\r
42 Td->CurrBufferPointer = NULL;\r
43 Td->NextTD = NULL;\r
44 Td->BufferEndPointer = NULL;\r
45 Td->NextTDPointer = NULL;\r
46\r
47 return Td;\r
48}\r
49\r
50\r
51/**\r
52\r
53 Free a TD\r
54\r
55 @Param Ohc UHC private data\r
56 @Param Td Pointer to a TD to free\r
57\r
58 @retval EFI_SUCCESS TD freed\r
59\r
60**/\r
61EFI_STATUS\r
62OhciFreeTD (\r
63 IN USB_OHCI_HC_DEV *Ohc,\r
64 IN TD_DESCRIPTOR *Td\r
65 )\r
66{\r
67 if (Td == NULL) {\r
68 return EFI_SUCCESS;\r
69 }\r
70 UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));\r
71\r
72 return EFI_SUCCESS;\r
73}\r
74\r
75\r
76/**\r
77\r
78 Create a ED\r
79\r
80 @Param Ohc Device private data\r
81\r
82 @retval ED descriptor pointer\r
83\r
84**/\r
85ED_DESCRIPTOR *\r
86OhciCreateED (\r
87 USB_OHCI_HC_DEV *Ohc\r
88 )\r
89{\r
90 ED_DESCRIPTOR *Ed;\r
91 Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));\r
92 if (Ed == NULL) {\r
93 return NULL;\r
94 }\r
95 Ed->Word0.Skip = 1;\r
96 Ed->TdTailPointer = NULL;\r
97 Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) NULL);\r
98 Ed->NextED = NULL;\r
99\r
100 return Ed;\r
101}\r
102\r
103/**\r
104\r
105 Free a ED\r
106\r
107 @Param Ohc UHC private data\r
108 @Param Ed Pointer to a ED to free\r
109\r
110 @retval EFI_SUCCESS ED freed\r
111\r
112**/\r
113\r
114EFI_STATUS\r
115OhciFreeED (\r
116 IN USB_OHCI_HC_DEV *Ohc,\r
117 IN ED_DESCRIPTOR *Ed\r
118 )\r
119{\r
120 if (Ed == NULL) {\r
121 return EFI_SUCCESS;\r
122 }\r
123 UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));\r
124\r
125 return EFI_SUCCESS;\r
126}\r
127\r
128/**\r
129\r
130 Free ED\r
131\r
132 @Param Ohc Device private data\r
133 @Param Ed Pointer to a ED to free\r
134\r
135 @retval EFI_SUCCESS ED freed\r
136\r
137**/\r
138EFI_STATUS\r
139OhciFreeAllTDFromED (\r
140 IN USB_OHCI_HC_DEV *Ohc,\r
141 IN ED_DESCRIPTOR *Ed\r
142 )\r
143{\r
144 TD_DESCRIPTOR *HeadTd;\r
145 TD_DESCRIPTOR *TailTd;\r
146 TD_DESCRIPTOR *Td;\r
147 TD_DESCRIPTOR *TempTd;\r
148\r
149 if (Ed == NULL) {\r
150 return EFI_SUCCESS;\r
151 }\r
152\r
153 HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
154 TailTd = Ed->TdTailPointer;\r
155\r
156 Td = HeadTd;\r
157 while (Td != TailTd) {\r
158 TempTd = Td;\r
159 Td = Td->NextTDPointer;\r
160 OhciFreeTD (Ohc, TempTd);\r
161 }\r
162\r
163 return EFI_SUCCESS;\r
164}\r
165\r
166/**\r
167\r
168 Attach an ED\r
169\r
170 @Param Ed Ed to be attached\r
171 @Param NewEd Ed to attach\r
172\r
173 @retval EFI_SUCCESS NewEd attached to Ed\r
174 @retval EFI_INVALID_PARAMETER Ed is NULL\r
175\r
176**/\r
177EFI_STATUS\r
178OhciAttachED (\r
179 IN ED_DESCRIPTOR *Ed,\r
180 IN ED_DESCRIPTOR *NewEd\r
181 )\r
182{\r
183 ED_DESCRIPTOR *Temp;\r
184\r
185 if (Ed == NULL) {\r
186 return EFI_INVALID_PARAMETER;\r
187 }\r
188\r
189 if (Ed->NextED == NULL){\r
190 Ed->NextED = NewEd;\r
191 } else {\r
192 Temp = Ed->NextED;\r
193 Ed->NextED = NewEd;\r
194 NewEd->NextED = Temp;\r
195 }\r
196\r
197 return EFI_SUCCESS;\r
198}\r
199/**\r
200\r
201 Attach an ED to an ED list\r
202\r
203 @Param OHC UHC private data\r
204 @Param ListType Type of the ED list\r
205 @Param Ed ED to attach\r
206 @Param EdList ED list to be attached\r
207\r
208 @retval EFI_SUCCESS ED attached to ED list\r
209\r
210**/\r
211EFI_STATUS\r
212OhciAttachEDToList (\r
213 IN USB_OHCI_HC_DEV *Ohc,\r
214 IN DESCRIPTOR_LIST_TYPE ListType,\r
215 IN ED_DESCRIPTOR *Ed,\r
216 IN ED_DESCRIPTOR *EdList\r
217 )\r
218{\r
219 ED_DESCRIPTOR *HeadEd;\r
220\r
221 switch(ListType) {\r
222 case CONTROL_LIST:\r
223 HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);\r
224 if (HeadEd == NULL) {\r
225 OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);\r
226 } else {\r
227 OhciAttachED (HeadEd, Ed);\r
228 }\r
229 break;\r
230\r
231 case BULK_LIST:\r
232 HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);\r
233 if (HeadEd == NULL) {\r
234 OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);\r
235 } else {\r
236 OhciAttachED (HeadEd, Ed);\r
237 }\r
238 break;\r
239\r
240 case INTERRUPT_LIST:\r
241 OhciAttachED (EdList, Ed);\r
242 break;\r
243\r
244 default:\r
245 ASSERT (FALSE);\r
246 }\r
247\r
248 return EFI_SUCCESS;\r
249}\r
250/**\r
251\r
252 Link Td2 to the end of Td1\r
253\r
254 @Param Td1 TD to be linked\r
255 @Param Td2 TD to link\r
256\r
257 @retval EFI_SUCCESS TD successfully linked\r
258 @retval EFI_INVALID_PARAMETER Td1 is NULL\r
259\r
260**/\r
261EFI_STATUS\r
262OhciLinkTD (\r
263 IN TD_DESCRIPTOR *Td1,\r
264 IN TD_DESCRIPTOR *Td2\r
265 )\r
266{\r
267 TD_DESCRIPTOR *TempTd;\r
268\r
269 if (Td1 == NULL) {\r
270 return EFI_INVALID_PARAMETER;\r
271 }\r
272\r
273 if (Td1 == Td2) {\r
274 return EFI_SUCCESS;\r
275 }\r
276\r
277 TempTd = Td1;\r
278 while (TempTd->NextTD != NULL) {\r
279 TempTd = TempTd->NextTD;\r
280 }\r
281\r
282 TempTd->NextTD = Td2;\r
283 TempTd->NextTDPointer = Td2;\r
284\r
285 return EFI_SUCCESS;\r
286}\r
287\r
288\r
289/**\r
290\r
291 Attach TD list to ED\r
292\r
293 @Param Ed ED which TD list attach on\r
294 @Param HeadTd Head of the TD list to attach\r
295\r
296 @retval EFI_SUCCESS TD list attached on the ED\r
297\r
298**/\r
299EFI_STATUS\r
300OhciAttachTDListToED (\r
301 IN ED_DESCRIPTOR *Ed,\r
302 IN TD_DESCRIPTOR *HeadTd\r
303 )\r
304{\r
305 TD_DESCRIPTOR *TempTd;\r
306\r
307 TempTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
308\r
309 if (TempTd != NULL) {\r
310 while (TempTd->NextTD != NULL) {\r
311 TempTd = TempTd->NextTD;\r
312 }\r
313 TempTd->NextTD = HeadTd;\r
314 TempTd->NextTDPointer = HeadTd;\r
315 } else {\r
316 Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) HeadTd);\r
317 }\r
318\r
319 return EFI_SUCCESS;\r
320}\r
321\r
322\r
323/**\r
324\r
325 Set value to ED specific field\r
326\r
327 @Param Ed ED to be set\r
328 @Param Field Field to be set\r
329 @Param Value Value to set\r
330\r
331 @retval EFI_SUCCESS Value set\r
332\r
333**/\r
334EFI_STATUS\r
335OhciSetEDField (\r
336 IN ED_DESCRIPTOR *Ed,\r
337 IN UINT32 Field,\r
338 IN UINT32 Value\r
339 )\r
340{\r
341 if (Field & ED_FUNC_ADD) {\r
342 Ed->Word0.FunctionAddress = Value;\r
343 }\r
344 if (Field & ED_ENDPT_NUM) {\r
345 Ed->Word0.EndPointNum = Value;\r
346 }\r
347 if (Field & ED_DIR) {\r
348 Ed->Word0.Direction = Value;\r
349 }\r
350 if (Field & ED_SPEED) {\r
351 Ed->Word0.Speed = Value;\r
352 }\r
353 if (Field & ED_SKIP) {\r
354 Ed->Word0.Skip = Value;\r
355 }\r
356 if (Field & ED_FORMAT) {\r
357 Ed->Word0.Format = Value;\r
358 }\r
359 if (Field & ED_MAX_PACKET) {\r
360 Ed->Word0.MaxPacketSize = Value;\r
361 }\r
362 if (Field & ED_PDATA) {\r
363 Ed->Word0.FreeSpace = Value;\r
364 }\r
365 if (Field & ED_ZERO) {\r
366 Ed->Word2.Zero = Value;\r
367 }\r
368 if (Field & ED_TDTAIL_PTR) {\r
369 Ed->TdTailPointer = (VOID *) Value;\r
370 }\r
371\r
372 if (Field & ED_HALTED) {\r
373 Ed->Word2.Halted = Value;\r
374 }\r
375 if (Field & ED_DTTOGGLE) {\r
376 Ed->Word2.ToggleCarry = Value;\r
377 }\r
378 if (Field & ED_TDHEAD_PTR) {\r
379 Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);\r
380 }\r
381\r
382 if (Field & ED_NEXT_EDPTR) {\r
383 Ed->NextED = (VOID *) Value;\r
384 }\r
385\r
386 return EFI_SUCCESS;\r
387}\r
388\r
389/**\r
390\r
391 Get value from an ED's specific field\r
392\r
393 @Param Ed ED pointer\r
394 @Param Field Field to get value from\r
395\r
396 @retval Value of the field\r
397\r
398**/\r
399UINT32\r
400OhciGetEDField (\r
401 IN ED_DESCRIPTOR *Ed,\r
402 IN UINT32 Field\r
403 )\r
404{\r
405 switch (Field) {\r
406 case ED_FUNC_ADD:\r
407 return Ed->Word0.FunctionAddress;\r
408 break;\r
409 case ED_ENDPT_NUM:\r
410 return Ed->Word0.EndPointNum;\r
411 break;\r
412 case ED_DIR:\r
413 return Ed->Word0.Direction;\r
414 break;\r
415 case ED_SPEED:\r
416 return Ed->Word0.Speed;\r
417 break;\r
418 case ED_SKIP:\r
419 return Ed->Word0.Skip;\r
420 break;\r
421 case ED_FORMAT:\r
422 return Ed->Word0.Format;\r
423 break;\r
424 case ED_MAX_PACKET:\r
425 return Ed->Word0.MaxPacketSize;\r
426 break;\r
427\r
428 case ED_TDTAIL_PTR:\r
429 return (UINT32) Ed->TdTailPointer;\r
430 break;\r
431\r
432 case ED_HALTED:\r
433 return Ed->Word2.Halted;\r
434 break;\r
435\r
436 case ED_DTTOGGLE:\r
437 return Ed->Word2.ToggleCarry;\r
438 break;\r
439\r
440 case ED_TDHEAD_PTR:\r
441 return Ed->Word2.TdHeadPointer << 4;\r
442 break;\r
443\r
444 case ED_NEXT_EDPTR:\r
445 return (UINT32) Ed->NextED;\r
446 break;\r
447\r
448 default:\r
449 ASSERT (FALSE);\r
450 }\r
451\r
452 return 0;\r
453}\r
454\r
455\r
456/**\r
457\r
458 Set value to TD specific field\r
459\r
460 @Param Td TD to be set\r
461 @Param Field Field to be set\r
462 @Param Value Value to set\r
463\r
464 @retval EFI_SUCCESS Value set\r
465\r
466**/\r
467EFI_STATUS\r
468OhciSetTDField (\r
469 IN TD_DESCRIPTOR *Td,\r
470 IN UINT32 Field,\r
471 IN UINT32 Value\r
472 )\r
473{\r
474 if (Field & TD_PDATA) {\r
475 Td->Word0.Reserved = Value;\r
476 }\r
477 if (Field & TD_BUFFER_ROUND) {\r
478 Td->Word0.BufferRounding = Value;\r
479 }\r
480 if (Field & TD_DIR_PID) {\r
481 Td->Word0.DirPID = Value;\r
482 }\r
483 if (Field & TD_DELAY_INT) {\r
484 Td->Word0.DelayInterrupt = Value;\r
485 }\r
486 if (Field & TD_DT_TOGGLE) {\r
487 Td->Word0.DataToggle = Value | 0x2;\r
488 }\r
489 if (Field & TD_ERROR_CNT) {\r
490 Td->Word0.ErrorCount = Value;\r
491 }\r
492 if (Field & TD_COND_CODE) {\r
493 Td->Word0.ConditionCode = Value;\r
494 }\r
495\r
496 if (Field & TD_CURR_BUFFER_PTR) {\r
497 Td->CurrBufferPointer = (VOID *) Value;\r
498 }\r
499\r
500\r
501 if (Field & TD_NEXT_PTR) {\r
502 Td->NextTD = (VOID *) Value;\r
503 }\r
504\r
505 if (Field & TD_BUFFER_END_PTR) {\r
506 Td->BufferEndPointer = (VOID *) Value;\r
507 }\r
508\r
509 return EFI_SUCCESS;\r
510}\r
511\r
512\r
513/**\r
514\r
515 Get value from ED specific field\r
516\r
517 @Param Td TD pointer\r
518 @Param Field Field to get value from\r
519\r
520 @retval Value of the field\r
521\r
522**/\r
523\r
524UINT32\r
525OhciGetTDField (\r
526 IN TD_DESCRIPTOR *Td,\r
527 IN UINT32 Field\r
528 )\r
529{\r
530 switch (Field){\r
531 case TD_BUFFER_ROUND:\r
532 return Td->Word0.BufferRounding;\r
533 break;\r
534 case TD_DIR_PID:\r
535 return Td->Word0.DirPID;\r
536 break;\r
537 case TD_DELAY_INT:\r
538 return Td->Word0.DelayInterrupt;\r
539 break;\r
540 case TD_DT_TOGGLE:\r
541 return Td->Word0.DataToggle;\r
542 break;\r
543 case TD_ERROR_CNT:\r
544 return Td->Word0.ErrorCount;\r
545 break;\r
546 case TD_COND_CODE:\r
547 return Td->Word0.ConditionCode;\r
548 break;\r
549 case TD_CURR_BUFFER_PTR:\r
550 return (UINT32) Td->CurrBufferPointer;\r
551 break;\r
552\r
553 case TD_NEXT_PTR:\r
554 return (UINT32) Td->NextTD;\r
555 break;\r
556\r
557 case TD_BUFFER_END_PTR:\r
558 return (UINT32) Td->BufferEndPointer;\r
559 break;\r
560\r
561 default:\r
562 ASSERT (FALSE);\r
563 }\r
564\r
565 return 0;\r
566}\r