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