]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c
28d73daffef09cb07054f0653c2e06424b7ee9d6
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbUtility.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 UsbUtility.c
15
16 Abstract:
17
18 Wrapper function for usb host controller interface
19
20 Revision History
21
22
23 **/
24
25
26 #include "UsbBus.h"
27
28
29 /**
30 Get the capability of the host controller
31
32 @param UsbBus The usb driver
33 @param MaxSpeed The maximum speed this host controller supports
34 @param NumOfPort The number of the root hub port
35 @param Is64BitCapable Whether this controller support 64 bit addressing
36
37 @retval EFI_SUCCESS The host controller capability is returned
38 @retval Others Failed to retrieve the host controller capability.
39
40 **/
41 EFI_STATUS
42 UsbHcGetCapability (
43 IN USB_BUS *UsbBus,
44 OUT UINT8 *MaxSpeed,
45 OUT UINT8 *NumOfPort,
46 OUT UINT8 *Is64BitCapable
47 )
48 {
49 EFI_STATUS Status;
50
51 if (UsbBus->Usb2Hc != NULL) {
52 Status = UsbBus->Usb2Hc->GetCapability (
53 UsbBus->Usb2Hc,
54 MaxSpeed,
55 NumOfPort,
56 Is64BitCapable
57 );
58
59 } else {
60 Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort);
61
62 *MaxSpeed = EFI_USB_SPEED_FULL;
63 *Is64BitCapable = (UINT8) FALSE;
64 }
65
66 return Status;
67 }
68
69
70 /**
71 Reset the host controller
72
73 @param UsbBus The usb bus driver
74 @param Attributes The reset type, only global reset is used by this driver
75
76 @return GC_TODO: add return values
77
78 **/
79 EFI_STATUS
80 UsbHcReset (
81 IN USB_BUS *UsbBus,
82 IN UINT16 Attributes
83 )
84 {
85 EFI_STATUS Status;
86
87 if (UsbBus->Usb2Hc != NULL) {
88 Status = UsbBus->Usb2Hc->Reset (UsbBus->Usb2Hc, Attributes);
89 } else {
90 Status = UsbBus->UsbHc->Reset (UsbBus->UsbHc, Attributes);
91 }
92
93 return Status;
94 }
95
96
97 /**
98 Get the current operation state of the host controller
99
100 @param UsbBus The USB bus driver
101 @param State The host controller operation state
102
103 @retval EFI_SUCCESS The operation state is returned in State
104 @retval Others Failed to get the host controller state
105
106 **/
107 EFI_STATUS
108 UsbHcGetState (
109 IN USB_BUS *UsbBus,
110 OUT EFI_USB_HC_STATE *State
111 )
112 {
113 EFI_STATUS Status;
114
115 if (UsbBus->Usb2Hc != NULL) {
116 Status = UsbBus->Usb2Hc->GetState (UsbBus->Usb2Hc, State);
117 } else {
118 Status = UsbBus->UsbHc->GetState (UsbBus->UsbHc, State);
119 }
120
121 return Status;
122 }
123
124
125 /**
126 Set the host controller operation state
127
128 @param UsbBus The USB bus driver
129 @param State The state to set
130
131 @retval EFI_SUCCESS The host controller is now working at State
132 @retval Others Failed to set operation state
133
134 **/
135 EFI_STATUS
136 UsbHcSetState (
137 IN USB_BUS *UsbBus,
138 IN EFI_USB_HC_STATE State
139 )
140 {
141 EFI_STATUS Status;
142
143 if (UsbBus->Usb2Hc != NULL) {
144 Status = UsbBus->Usb2Hc->SetState (UsbBus->Usb2Hc, State);
145 } else {
146 Status = UsbBus->UsbHc->SetState (UsbBus->UsbHc, State);
147 }
148
149 return Status;
150 }
151
152
153 /**
154 Get the root hub port state
155
156 @param UsbBus The USB bus driver
157 @param PortIndex The index of port
158 @param PortStatus The variable to save port state
159
160 @retval EFI_SUCCESS The root port state is returned in
161 @retval Others Failed to get the root hub port state
162
163 **/
164 EFI_STATUS
165 UsbHcGetRootHubPortStatus (
166 IN USB_BUS *UsbBus,
167 IN UINT8 PortIndex,
168 OUT EFI_USB_PORT_STATUS *PortStatus
169 )
170 {
171 EFI_STATUS Status;
172
173 if (UsbBus->Usb2Hc != NULL) {
174 Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus);
175 } else {
176 Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus);
177 }
178
179 return Status;
180 }
181
182
183 /**
184 Set the root hub port feature
185
186 @param UsbBus The USB bus driver
187 @param PortIndex The port index
188 @param Feature The port feature to set
189
190 @retval EFI_SUCCESS The port feature is set
191 @retval Others Failed to set port feature
192
193 **/
194 EFI_STATUS
195 UsbHcSetRootHubPortFeature (
196 IN USB_BUS *UsbBus,
197 IN UINT8 PortIndex,
198 IN EFI_USB_PORT_FEATURE Feature
199 )
200 {
201 EFI_STATUS Status;
202
203
204 if (UsbBus->Usb2Hc != NULL) {
205 Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
206 } else {
207 Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
208 }
209
210 return Status;
211 }
212
213
214 /**
215 Clear the root hub port feature
216
217 @param UsbBus The USB bus driver
218 @param PortIndex The port index
219 @param Feature The port feature to clear
220
221 @retval EFI_SUCCESS The port feature is clear
222 @retval Others Failed to clear port feature
223
224 **/
225 EFI_STATUS
226 UsbHcClearRootHubPortFeature (
227 IN USB_BUS *UsbBus,
228 IN UINT8 PortIndex,
229 IN EFI_USB_PORT_FEATURE Feature
230 )
231 {
232 EFI_STATUS Status;
233
234 if (UsbBus->Usb2Hc != NULL) {
235 Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
236 } else {
237 Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
238 }
239
240 return Status;
241 }
242
243
244 /**
245 Execute a control transfer to the device
246
247 @param UsbBus The USB bus driver
248 @param DevAddr The device address
249 @param DevSpeed The device speed
250 @param MaxPacket Maximum packet size of endpoint 0
251 @param Request The control transfer request
252 @param Direction The direction of data stage
253 @param Data The buffer holding data
254 @param DataLength The length of the data
255 @param TimeOut Timeout (in ms) to wait until timeout
256 @param Translator The transaction translator for low/full speed device
257 @param UsbResult The result of transfer
258
259 @retval EFI_SUCCESS The control transfer finished without error
260 @retval Others The control transfer failed, reason returned in UsbReslt
261
262 **/
263 EFI_STATUS
264 UsbHcControlTransfer (
265 IN USB_BUS *UsbBus,
266 IN UINT8 DevAddr,
267 IN UINT8 DevSpeed,
268 IN UINTN MaxPacket,
269 IN EFI_USB_DEVICE_REQUEST *Request,
270 IN EFI_USB_DATA_DIRECTION Direction,
271 IN OUT VOID *Data,
272 IN OUT UINTN *DataLength,
273 IN UINTN TimeOut,
274 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
275 OUT UINT32 *UsbResult
276 )
277 {
278 EFI_STATUS Status;
279 BOOLEAN IsSlowDevice;
280
281 if (UsbBus->Usb2Hc != NULL) {
282 Status = UsbBus->Usb2Hc->ControlTransfer (
283 UsbBus->Usb2Hc,
284 DevAddr,
285 DevSpeed,
286 MaxPacket,
287 Request,
288 Direction,
289 Data,
290 DataLength,
291 TimeOut,
292 Translator,
293 UsbResult
294 );
295
296 } else {
297 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
298 Status = UsbBus->UsbHc->ControlTransfer (
299 UsbBus->UsbHc,
300 DevAddr,
301 IsSlowDevice,
302 (UINT8) MaxPacket,
303 Request,
304 Direction,
305 Data,
306 DataLength,
307 TimeOut,
308 UsbResult
309 );
310 }
311
312 return Status;
313 }
314
315
316 /**
317 Execute a bulk transfer to the device's endpoint
318
319 @param UsbBus The USB bus driver
320 @param DevAddr The target device address
321 @param EpAddr The target endpoint address, with direction encoded in
322 bit 7
323 @param DevSpeed The device's speed
324 @param MaxPacket The endpoint's max packet size
325 @param BufferNum The number of data buffer
326 @param Data Array of pointers to data buffer
327 @param DataLength The length of data buffer
328 @param DataToggle On input, the initial data toggle to use, also return
329 the next toggle on output.
330 @param TimeOut The time to wait until timeout
331 @param Translator The transaction translator for low/full speed device
332 @param UsbResult The result of USB execution
333
334 @retval EFI_SUCCESS The bulk transfer is finished without error
335 @retval Others Failed to execute bulk transfer, result in UsbResult
336
337 **/
338 EFI_STATUS
339 UsbHcBulkTransfer (
340 IN USB_BUS *UsbBus,
341 IN UINT8 DevAddr,
342 IN UINT8 EpAddr,
343 IN UINT8 DevSpeed,
344 IN UINTN MaxPacket,
345 IN UINT8 BufferNum,
346 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
347 IN OUT UINTN *DataLength,
348 IN OUT UINT8 *DataToggle,
349 IN UINTN TimeOut,
350 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
351 OUT UINT32 *UsbResult
352 )
353 {
354 EFI_STATUS Status;
355
356 if (UsbBus->Usb2Hc != NULL) {
357 Status = UsbBus->Usb2Hc->BulkTransfer (
358 UsbBus->Usb2Hc,
359 DevAddr,
360 EpAddr,
361 DevSpeed,
362 MaxPacket,
363 BufferNum,
364 Data,
365 DataLength,
366 DataToggle,
367 TimeOut,
368 Translator,
369 UsbResult
370 );
371 } else {
372 Status = UsbBus->UsbHc->BulkTransfer (
373 UsbBus->UsbHc,
374 DevAddr,
375 EpAddr,
376 (UINT8) MaxPacket,
377 *Data,
378 DataLength,
379 DataToggle,
380 TimeOut,
381 UsbResult
382 );
383 }
384
385 return Status;
386 }
387
388
389 /**
390 Queue or cancel an asynchronous interrupt transfer
391
392 @param UsbBus The USB bus driver
393 @param DevAddr The target device address
394 @param EpAddr The target endpoint address, with direction encoded in
395 bit 7
396 @param DevSpeed The device's speed
397 @param MaxPacket The endpoint's max packet size
398 @param IsNewTransfer Whether this is a new request. If not, cancel the old
399 request
400 @param DataToggle Data toggle to use on input, next toggle on output
401 @param PollingInterval The interval to poll the interrupt transfer (in ms)
402 @param DataLength The length of periodical data receive
403 @param Translator The transaction translator for low/full speed device
404 @param Callback Function to call when data is received
405 @param Context The context to the callback
406
407 @retval EFI_SUCCESS The asynchronous transfer is queued
408 @retval Others Failed to queue the transfer
409
410 **/
411 EFI_STATUS
412 UsbHcAsyncInterruptTransfer (
413 IN USB_BUS *UsbBus,
414 IN UINT8 DevAddr,
415 IN UINT8 EpAddr,
416 IN UINT8 DevSpeed,
417 IN UINTN MaxPacket,
418 IN BOOLEAN IsNewTransfer,
419 IN OUT UINT8 *DataToggle,
420 IN UINTN PollingInterval,
421 IN UINTN DataLength,
422 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
423 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
424 IN VOID *Context OPTIONAL
425 )
426 {
427 EFI_STATUS Status;
428 BOOLEAN IsSlowDevice;
429
430 if (UsbBus->Usb2Hc != NULL) {
431 Status = UsbBus->Usb2Hc->AsyncInterruptTransfer (
432 UsbBus->Usb2Hc,
433 DevAddr,
434 EpAddr,
435 DevSpeed,
436 MaxPacket,
437 IsNewTransfer,
438 DataToggle,
439 PollingInterval,
440 DataLength,
441 Translator,
442 Callback,
443 Context
444 );
445 } else {
446 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
447
448 Status = UsbBus->UsbHc->AsyncInterruptTransfer (
449 UsbBus->UsbHc,
450 DevAddr,
451 EpAddr,
452 IsSlowDevice,
453 (UINT8) MaxPacket,
454 IsNewTransfer,
455 DataToggle,
456 PollingInterval,
457 DataLength,
458 Callback,
459 Context
460 );
461 }
462
463 return Status;
464 }
465
466
467 /**
468 Execute a synchronous interrupt transfer to the target endpoint
469
470 @param UsbBus The USB bus driver
471 @param DevAddr The target device address
472 @param EpAddr The target endpoint address, with direction encoded in
473 bit 7
474 @param DevSpeed The device's speed
475 @param MaxPacket The endpoint's max packet size
476 @param Data Pointer to data buffer
477 @param DataLength The length of data buffer
478 @param DataToggle On input, the initial data toggle to use, also return
479 the next toggle on output.
480 @param TimeOut The time to wait until timeout
481 @param Translator The transaction translator for low/full speed device
482 @param UsbResult The result of USB execution
483
484 @retval EFI_SUCCESS The synchronous interrupt transfer is OK
485 @retval Others Failed to execute the synchronous interrupt transfer
486
487 **/
488 EFI_STATUS
489 UsbHcSyncInterruptTransfer (
490 IN USB_BUS *UsbBus,
491 IN UINT8 DevAddr,
492 IN UINT8 EpAddr,
493 IN UINT8 DevSpeed,
494 IN UINTN MaxPacket,
495 IN OUT VOID *Data,
496 IN OUT UINTN *DataLength,
497 IN OUT UINT8 *DataToggle,
498 IN UINTN TimeOut,
499 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
500 OUT UINT32 *UsbResult
501 )
502 {
503 EFI_STATUS Status;
504 BOOLEAN IsSlowDevice;
505
506 if (UsbBus->Usb2Hc != NULL) {
507 Status = UsbBus->Usb2Hc->SyncInterruptTransfer (
508 UsbBus->Usb2Hc,
509 DevAddr,
510 EpAddr,
511 DevSpeed,
512 MaxPacket,
513 Data,
514 DataLength,
515 DataToggle,
516 TimeOut,
517 Translator,
518 UsbResult
519 );
520 } else {
521 IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE);
522 Status = UsbBus->UsbHc->SyncInterruptTransfer (
523 UsbBus->UsbHc,
524 DevAddr,
525 EpAddr,
526 IsSlowDevice,
527 (UINT8) MaxPacket,
528 Data,
529 DataLength,
530 DataToggle,
531 TimeOut,
532 UsbResult
533 );
534 }
535
536 return Status;
537 }
538
539
540 /**
541 Execute a synchronous Isochronous USB transfer
542
543 @param UsbBus The USB bus driver
544 @param DevAddr The target device address
545 @param EpAddr The target endpoint address, with direction encoded in
546 bit 7
547 @param DevSpeed The device's speed
548 @param MaxPacket The endpoint's max packet size
549 @param BufferNum The number of data buffer
550 @param Data Array of pointers to data buffer
551 @param DataLength The length of data buffer
552 @param Translator The transaction translator for low/full speed device
553 @param UsbResult The result of USB execution
554
555 @retval EFI_UNSUPPORTED The isochronous transfer isn't supported now
556
557 **/
558 EFI_STATUS
559 UsbHcIsochronousTransfer (
560 IN USB_BUS *UsbBus,
561 IN UINT8 DevAddr,
562 IN UINT8 EpAddr,
563 IN UINT8 DevSpeed,
564 IN UINTN MaxPacket,
565 IN UINT8 BufferNum,
566 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
567 IN UINTN DataLength,
568 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
569 OUT UINT32 *UsbResult
570 )
571 {
572 return EFI_UNSUPPORTED;
573 }
574
575
576 /**
577 Queue an asynchronous isochronous transfer
578
579 @param UsbBus The USB bus driver
580 @param DevAddr The target device address
581 @param EpAddr The target endpoint address, with direction encoded in
582 bit 7
583 @param DevSpeed The device's speed
584 @param MaxPacket The endpoint's max packet size
585 @param BufferNum The number of data buffer
586 @param Data Array of pointers to data buffer
587 @param DataLength The length of data buffer
588 @param Translator The transaction translator for low/full speed device
589 @param Callback The function to call when data is transferred
590 @param Context The context to the callback function
591
592 @retval EFI_UNSUPPORTED The asynchronous isochronous transfer isn't supported
593
594 **/
595 EFI_STATUS
596 UsbHcAsyncIsochronousTransfer (
597 IN USB_BUS *UsbBus,
598 IN UINT8 DevAddr,
599 IN UINT8 EpAddr,
600 IN UINT8 DevSpeed,
601 IN UINTN MaxPacket,
602 IN UINT8 BufferNum,
603 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
604 IN UINTN DataLength,
605 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
606 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
607 IN VOID *Context
608 )
609 {
610 return EFI_UNSUPPORTED;
611 }
612
613
614 /**
615 Open the USB host controller protocol BY_CHILD
616
617 @param Bus The USB bus driver
618 @param Child The child handle
619
620 @return The open protocol return
621
622 **/
623 EFI_STATUS
624 UsbOpenHostProtoByChild (
625 IN USB_BUS *Bus,
626 IN EFI_HANDLE Child
627 )
628 {
629 EFI_USB_HC_PROTOCOL *UsbHc;
630 EFI_USB2_HC_PROTOCOL *Usb2Hc;
631 EFI_STATUS Status;
632
633 if (Bus->Usb2Hc != NULL) {
634 Status = gBS->OpenProtocol (
635 Bus->HostHandle,
636 &gEfiUsb2HcProtocolGuid,
637 (VOID **) &Usb2Hc,
638 mUsbBusDriverBinding.DriverBindingHandle,
639 Child,
640 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
641 );
642
643 } else {
644 Status = gBS->OpenProtocol (
645 Bus->HostHandle,
646 &gEfiUsbHcProtocolGuid,
647 (VOID **) &UsbHc,
648 mUsbBusDriverBinding.DriverBindingHandle,
649 Child,
650 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
651 );
652 }
653
654 return Status;
655 }
656
657
658 /**
659 Close the USB host controller protocol BY_CHILD
660
661 @param Bus The USB bus driver
662 @param Child The child handle
663
664 @return None
665
666 **/
667 VOID
668 UsbCloseHostProtoByChild (
669 IN USB_BUS *Bus,
670 IN EFI_HANDLE Child
671 )
672 {
673 if (Bus->Usb2Hc != NULL) {
674 gBS->CloseProtocol (
675 Bus->HostHandle,
676 &gEfiUsb2HcProtocolGuid,
677 mUsbBusDriverBinding.DriverBindingHandle,
678 Child
679 );
680
681 } else {
682 gBS->CloseProtocol (
683 Bus->HostHandle,
684 &gEfiUsbHcProtocolGuid,
685 mUsbBusDriverBinding.DriverBindingHandle,
686 Child
687 );
688 }
689 }
690
691
692
693 /**
694 return the current TPL, copied from the EDKII glue lib.
695
696 VOID
697
698 @return Current TPL
699
700 **/
701 EFI_TPL
702 UsbGetCurrentTpl (
703 VOID
704 )
705 {
706 EFI_TPL Tpl;
707
708 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
709 gBS->RestoreTPL (Tpl);
710
711 return Tpl;
712 }
713
714
715 #ifdef EFI_DEBUG
716 VOID
717 UsbDebug (
718 IN CHAR8 *Format,
719 ...
720 )
721 /*++
722
723 Routine Description:
724
725 USB's debug output function.
726
727 Arguments:
728
729 Format - The format parameters to the print
730 ... - The variable length parameters after format
731
732 Returns:
733
734 None
735
736 --*/
737 {
738 VA_LIST Marker;
739
740 VA_START (Marker, Format);
741 DebugVPrint (DEBUG_INFO, Format, Marker);
742 VA_END (Marker);
743 }
744
745
746
747 /**
748 USB's error output function.
749
750 @param Format The format parameters to the print
751 @param ... The variable length parameters after format
752
753 @return None
754
755 **/
756 VOID
757 UsbError (
758 IN CHAR8 *Format,
759 ...
760 )
761 {
762 VA_LIST Marker;
763
764 VA_START (Marker, Format);
765 DebugVPrint (DEBUG_ERROR, Format, Marker);
766 VA_END (Marker);
767 }
768
769 #endif