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