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