• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
OhciCreateTD(IN USB_OHCI_HC_DEV * Ohc)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
OhciFreeTD(IN USB_OHCI_HC_DEV * Ohc,IN TD_DESCRIPTOR * Td)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 *
OhciCreateED(USB_OHCI_HC_DEV * Ohc)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
OhciFreeED(IN USB_OHCI_HC_DEV * Ohc,IN ED_DESCRIPTOR * Ed)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
OhciFreeAllTDFromED(IN USB_OHCI_HC_DEV * Ohc,IN ED_DESCRIPTOR * Ed)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
OhciAttachED(IN ED_DESCRIPTOR * Ed,IN ED_DESCRIPTOR * NewEd)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
OhciAttachEDToList(IN USB_OHCI_HC_DEV * Ohc,IN DESCRIPTOR_LIST_TYPE ListType,IN ED_DESCRIPTOR * Ed,IN ED_DESCRIPTOR * EdList)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
OhciLinkTD(IN TD_DESCRIPTOR * Td1,IN TD_DESCRIPTOR * Td2)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
OhciAttachTDListToED(IN ED_DESCRIPTOR * Ed,IN TD_DESCRIPTOR * HeadTd)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
OhciSetEDField(IN ED_DESCRIPTOR * Ed,IN UINT32 Field,IN UINT32 Value)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
OhciGetEDField(IN ED_DESCRIPTOR * Ed,IN UINT32 Field)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
OhciSetTDField(IN TD_DESCRIPTOR * Td,IN UINT32 Field,IN UINT32 Value)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
OhciGetTDField(IN TD_DESCRIPTOR * Td,IN UINT32 Field)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 }
567