]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
1. Add the GLOBAL_REMOVE_IF_UNREFERENCED to globe variables which are used only in...
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / usbio.c
1 /*++
2
3 Copyright (c) 2006, 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 UsbIo.c
15
16 Abstract:
17
18 USB I/O Abstraction Driver
19
20 Revision History
21
22 --*/
23
24 #include "usbbus.h"
25
26 //
27 // USB I/O Support Function Prototypes
28 //
29 STATIC
30 EFI_STATUS
31 EFIAPI
32 UsbControlTransfer (
33 IN EFI_USB_IO_PROTOCOL *This,
34 IN EFI_USB_DEVICE_REQUEST *Request,
35 IN EFI_USB_DATA_DIRECTION Direction,
36 IN UINT32 Timeout,
37 IN OUT VOID *Data, OPTIONAL
38 IN UINTN DataLength, OPTIONAL
39 OUT UINT32 *Status
40 );
41
42 STATIC
43 EFI_STATUS
44 EFIAPI
45 UsbBulkTransfer (
46 IN EFI_USB_IO_PROTOCOL *This,
47 IN UINT8 DeviceEndpoint,
48 IN OUT VOID *Data,
49 IN OUT UINTN *DataLength,
50 IN UINTN Timeout,
51 OUT UINT32 *Status
52 );
53
54 STATIC
55 EFI_STATUS
56 EFIAPI
57 UsbAsyncInterruptTransfer (
58 IN EFI_USB_IO_PROTOCOL * This,
59 IN UINT8 DeviceEndpoint,
60 IN BOOLEAN IsNewTransfer,
61 IN UINTN PollingInterval, OPTIONAL
62 IN UINTN DataLength, OPTIONAL
63 IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack, OPTIONAL
64 IN VOID *Context OPTIONAL
65 );
66
67 STATIC
68 EFI_STATUS
69 EFIAPI
70 UsbSyncInterruptTransfer (
71 IN EFI_USB_IO_PROTOCOL *This,
72 IN UINT8 DeviceEndpoint,
73 IN OUT VOID *Data,
74 IN OUT UINTN *DataLength,
75 IN UINTN Timeout,
76 OUT UINT32 *Status
77 );
78
79 STATIC
80 EFI_STATUS
81 EFIAPI
82 UsbIsochronousTransfer (
83 IN EFI_USB_IO_PROTOCOL *This,
84 IN UINT8 DeviceEndpoint,
85 IN OUT VOID *Data,
86 IN UINTN DataLength,
87 OUT UINT32 *Status
88 );
89
90 STATIC
91 EFI_STATUS
92 EFIAPI
93 UsbAsyncIsochronousTransfer (
94 IN EFI_USB_IO_PROTOCOL * This,
95 IN UINT8 DeviceEndpoint,
96 IN OUT VOID *Data,
97 IN UINTN DataLength,
98 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
99 IN VOID *Context OPTIONAL
100 );
101
102 extern
103 EFI_STATUS
104 EFIAPI
105 UsbPortReset (
106 IN EFI_USB_IO_PROTOCOL *This
107 );
108
109 STATIC
110 EFI_STATUS
111 EFIAPI
112 UsbGetDeviceDescriptor (
113 IN EFI_USB_IO_PROTOCOL *This,
114 OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor
115 );
116
117 STATIC
118 EFI_STATUS
119 EFIAPI
120 UsbGetActiveConfigDescriptor (
121 IN EFI_USB_IO_PROTOCOL *This,
122 OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor
123 );
124
125 STATIC
126 EFI_STATUS
127 EFIAPI
128 UsbGetInterfaceDescriptor (
129 IN EFI_USB_IO_PROTOCOL *This,
130 OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor
131 );
132
133 STATIC
134 EFI_STATUS
135 EFIAPI
136 UsbGetEndpointDescriptor (
137 IN EFI_USB_IO_PROTOCOL *This,
138 IN UINT8 EndpointIndex,
139 OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor
140 );
141
142 STATIC
143 EFI_STATUS
144 EFIAPI
145 UsbGetStringDescriptor (
146 IN EFI_USB_IO_PROTOCOL *This,
147 IN UINT16 LangID,
148 IN UINT8 StringIndex,
149 OUT CHAR16 **String
150 );
151
152 STATIC
153 EFI_STATUS
154 EFIAPI
155 UsbGetSupportedLanguages (
156 IN EFI_USB_IO_PROTOCOL *This,
157 OUT UINT16 **LangIDTable,
158 OUT UINT16 *TableSize
159 );
160
161 //
162 // USB I/O Interface structure
163 //
164 STATIC EFI_USB_IO_PROTOCOL UsbIoInterface = {
165 UsbControlTransfer,
166 UsbBulkTransfer,
167 UsbAsyncInterruptTransfer,
168 UsbSyncInterruptTransfer,
169 UsbIsochronousTransfer,
170 UsbAsyncIsochronousTransfer,
171 UsbGetDeviceDescriptor,
172 UsbGetActiveConfigDescriptor,
173 UsbGetInterfaceDescriptor,
174 UsbGetEndpointDescriptor,
175 UsbGetStringDescriptor,
176 UsbGetSupportedLanguages,
177 UsbPortReset
178 };
179
180 VOID
181 InitializeUsbIoInstance (
182 IN USB_IO_CONTROLLER_DEVICE *UsbIoController
183 )
184 /*++
185
186 Routine Description:
187
188 Initialize the instance of UsbIo controller
189
190 Arguments:
191
192 UsbIoController - A pointer to controller structure of UsbIo
193
194 Returns:
195
196 --*/
197 {
198 //
199 // Copy EFI_USB_IO protocol instance
200 //
201 CopyMem (
202 &UsbIoController->UsbIo,
203 &UsbIoInterface,
204 sizeof (EFI_USB_IO_PROTOCOL)
205 );
206 }
207 //
208 // Implementation
209 //
210 STATIC
211 EFI_STATUS
212 EFIAPI
213 UsbControlTransfer (
214 IN EFI_USB_IO_PROTOCOL *This,
215 IN EFI_USB_DEVICE_REQUEST *Request,
216 IN EFI_USB_DATA_DIRECTION Direction,
217 IN UINT32 Timeout,
218 IN OUT VOID *Data, OPTIONAL
219 IN UINTN DataLength, OPTIONAL
220 OUT UINT32 *Status
221 )
222 /*++
223
224 Routine Description:
225 This function is used to manage a USB device with a control transfer pipe.
226
227 Arguments:
228 This - Indicates calling context.
229 Request - A pointer to the USB device request that will be sent to
230 the USB device.
231 Direction - Indicates the data direction.
232 Data - A pointer to the buffer of data that will be transmitted
233 to USB device or received from USB device.
234 Timeout - Indicates the transfer should be completed within this time
235 frame.
236 DataLength - The size, in bytes, of the data buffer specified by Data.
237 Status - A pointer to the result of the USB transfer.
238
239 Returns:
240 EFI_SUCCESS
241 EFI_INVALID_PARAMETER
242 EFI_OUT_OF_RESOURCES
243 EFI_TIMEOUT
244 EFI_DEVICE_ERROR
245
246 --*/
247 {
248 USB_IO_CONTROLLER_DEVICE *UsbIoController;
249
250 EFI_STATUS RetStatus;
251 USB_IO_DEVICE *UsbIoDev;
252 UINT8 MaxPacketLength;
253 UINT32 TransferResult;
254 BOOLEAN Disconnected;
255 //
256 // Parameters Checking
257 //
258 if (Status == NULL) {
259 return EFI_INVALID_PARAMETER;
260 }
261
262 //
263 // leave the HostController's ControlTransfer
264 // to perform other parameters checking
265 //
266 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
267 UsbIoDev = UsbIoController->UsbDevice;
268
269 MaxPacketLength = UsbIoDev->DeviceDescriptor.MaxPacketSize0;
270
271
272 if (Request->Request == USB_DEV_CLEAR_FEATURE &&
273 Request->RequestType == 0x02 &&
274 Request->Value == EfiUsbEndpointHalt) {
275 //
276 //Reduce the remove delay time for system response
277 //
278 IsDeviceDisconnected (UsbIoController, &Disconnected);
279 if (!EFI_ERROR (Status) && Disconnected == TRUE) {
280 DEBUG ((gUSBErrorLevel, "Device is disconnected when trying reset\n"));
281 return EFI_DEVICE_ERROR;
282 }
283 }
284 //
285 // using HostController's ControlTransfer to complete the request
286 //
287 RetStatus = UsbVirtualHcControlTransfer (
288 UsbIoDev->BusController,
289 UsbIoDev->DeviceAddress,
290 UsbIoDev->DeviceSpeed,
291 MaxPacketLength,
292 Request,
293 Direction,
294 Data,
295 &DataLength,
296 (UINTN) Timeout,
297 UsbIoDev->Translator,
298 &TransferResult
299 );
300
301 *Status = TransferResult;
302
303 if (Request->Request == USB_DEV_CLEAR_FEATURE &&
304 Request->RequestType == 0x02 &&
305 Request->Value == EfiUsbEndpointHalt) {
306 //
307 // This is a UsbClearEndpointHalt request
308 // Need to clear data toggle
309 // Request.Index == EndpointAddress
310 //
311 if (!EFI_ERROR (RetStatus) && TransferResult == EFI_USB_NOERROR) {
312 SetDataToggleBit (
313 This,
314 (UINT8) Request->Index,
315 0
316 );
317 }
318 }
319 return RetStatus;
320 }
321
322 STATIC
323 EFI_STATUS
324 EFIAPI
325 UsbBulkTransfer (
326 IN EFI_USB_IO_PROTOCOL *This,
327 IN UINT8 DeviceEndpoint,
328 IN OUT VOID *Data,
329 IN OUT UINTN *DataLength,
330 IN UINTN Timeout,
331 OUT UINT32 *Status
332 )
333 /*++
334
335 Routine Description:
336 This function is used to manage a USB device with the bulk transfer pipe.
337
338 Arguments:
339 This - Indicates calling context.
340 DeviceEndpoint - The destination USB device endpoint to which the device
341 request is being sent.
342 Data - A pointer to the buffer of data that will be transmitted
343 to USB device or received from USB device.
344 DataLength - On input, the size, in bytes, of the data buffer
345 specified by Data. On output, the number of bytes that
346 were actually transferred.
347 Timeout - Indicates the transfer should be completed within this
348 time frame.
349 Status - This parameter indicates the USB transfer status.
350
351 Returns:
352 EFI_SUCCESS
353 EFI_INVALID_PARAMETER
354 EFI_OUT_OF_RESOURCES
355 EFI_TIMEOUT
356 EFI_DEVICE_ERROR
357
358 --*/
359 {
360 USB_IO_DEVICE *UsbIoDev;
361 UINTN MaxPacketLength;
362 UINT8 DataToggle;
363 UINT8 OldToggle;
364 EFI_STATUS RetStatus;
365 USB_IO_CONTROLLER_DEVICE *UsbIoController;
366 ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
367 UINT8 DataBuffersNumber;
368 UINT32 TransferResult;
369
370 DataBuffersNumber = 1;
371 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
372 UsbIoDev = UsbIoController->UsbDevice;
373
374 //
375 // Parameters Checking
376 //
377 if ((DeviceEndpoint & 0x7F) == 0) {
378 return EFI_INVALID_PARAMETER;
379 }
380
381 if ((DeviceEndpoint & 0x7F) > 15) {
382 return EFI_INVALID_PARAMETER;
383 }
384
385 if (Status == NULL) {
386 return EFI_INVALID_PARAMETER;
387 }
388
389 EndPointListEntry = FindEndPointListEntry (
390 This,
391 DeviceEndpoint
392 );
393
394 if (EndPointListEntry == NULL) {
395 return EFI_INVALID_PARAMETER;
396 }
397
398 if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x02) {
399 return EFI_INVALID_PARAMETER;
400 }
401
402 //
403 // leave the HostController's BulkTransfer
404 // to perform other parameters checking
405 //
406 GetDeviceEndPointMaxPacketLength (
407 This,
408 DeviceEndpoint,
409 &MaxPacketLength
410 );
411
412 GetDataToggleBit (
413 This,
414 DeviceEndpoint,
415 &DataToggle
416 );
417
418 OldToggle = DataToggle;
419
420 //
421 // using HostController's BulkTransfer to complete the request
422 //
423 RetStatus = UsbVirtualHcBulkTransfer (
424 UsbIoDev->BusController,
425 UsbIoDev->DeviceAddress,
426 DeviceEndpoint,
427 UsbIoDev->DeviceSpeed,
428 MaxPacketLength,
429 DataBuffersNumber,
430 &Data,
431 DataLength,
432 &DataToggle,
433 Timeout,
434 UsbIoDev->Translator,
435 &TransferResult
436 );
437
438 if (OldToggle != DataToggle) {
439 //
440 // Write the toggle back
441 //
442 SetDataToggleBit (
443 This,
444 DeviceEndpoint,
445 DataToggle
446 );
447 }
448
449 *Status = TransferResult;
450
451 return RetStatus;
452 }
453
454 STATIC
455 EFI_STATUS
456 EFIAPI
457 UsbSyncInterruptTransfer (
458 IN EFI_USB_IO_PROTOCOL *This,
459 IN UINT8 DeviceEndpoint,
460 IN OUT VOID *Data,
461 IN OUT UINTN *DataLength,
462 IN UINTN Timeout,
463 OUT UINT32 *Status
464 )
465 /*++
466
467 Routine Description:
468 Usb Sync Interrupt Transfer
469
470 Arguments:
471 This - Indicates calling context.
472 DeviceEndpoint - The destination USB device endpoint to which the device
473 request is being sent.
474 Data - A pointer to the buffer of data that will be transmitted
475 to USB device or received from USB device.
476 DataLength - On input, the size, in bytes, of the data buffer
477 specified by Data. On output, the number of bytes that
478 were actually transferred.
479 Timeout - Indicates the transfer should be completed within this
480 time frame.
481 Status - This parameter indicates the USB transfer status.
482
483 Returns:
484 EFI_SUCCESS
485 EFI_INVALID_PARAMETER
486 EFI_OUT_OF_RESOURCES
487 EFI_TIMEOUT
488 EFI_DEVICE_ERROR
489
490 --*/
491 {
492 USB_IO_DEVICE *UsbIoDev;
493 UINTN MaxPacketLength;
494 UINT8 DataToggle;
495 UINT8 OldToggle;
496 EFI_STATUS RetStatus;
497 USB_IO_CONTROLLER_DEVICE *UsbIoController;
498 ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
499
500 //
501 // Parameters Checking
502 //
503 if ((DeviceEndpoint & 0x7F) == 0) {
504 return EFI_INVALID_PARAMETER;
505 }
506
507 if ((DeviceEndpoint & 0x7F) > 15) {
508 return EFI_INVALID_PARAMETER;
509 }
510
511 if (Status == NULL) {
512 return EFI_INVALID_PARAMETER;
513 }
514
515 EndPointListEntry = FindEndPointListEntry (
516 This,
517 DeviceEndpoint
518 );
519
520 if (EndPointListEntry == NULL) {
521 return EFI_INVALID_PARAMETER;
522 }
523
524 if ((EndPointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {
525 return EFI_INVALID_PARAMETER;
526 }
527
528 //
529 // leave the HostController's SyncInterruptTransfer
530 // to perform other parameters checking
531 //
532 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
533 UsbIoDev = UsbIoController->UsbDevice;
534 GetDeviceEndPointMaxPacketLength (
535 This,
536 DeviceEndpoint,
537 &MaxPacketLength
538 );
539
540 GetDataToggleBit (
541 This,
542 DeviceEndpoint,
543 &DataToggle
544 );
545
546 OldToggle = DataToggle;
547 //
548 // using HostController's SyncInterruptTransfer to complete the request
549 //
550 RetStatus = UsbVirtualHcSyncInterruptTransfer (
551 UsbIoDev->BusController,
552 UsbIoDev->DeviceAddress,
553 DeviceEndpoint,
554 UsbIoDev->DeviceSpeed,
555 MaxPacketLength,
556 Data,
557 DataLength,
558 &DataToggle,
559 Timeout,
560 UsbIoDev->Translator,
561 Status
562 );
563
564 if (OldToggle != DataToggle) {
565 //
566 // Write the toggle back
567 //
568 SetDataToggleBit (
569 This,
570 DeviceEndpoint,
571 DataToggle
572 );
573 }
574
575 return RetStatus;
576 }
577
578 STATIC
579 EFI_STATUS
580 EFIAPI
581 UsbAsyncInterruptTransfer (
582 IN EFI_USB_IO_PROTOCOL *This,
583 IN UINT8 DeviceEndpoint,
584 IN BOOLEAN IsNewTransfer,
585 IN UINTN PollingInterval, OPTIONAL
586 IN UINTN DataLength, OPTIONAL
587 IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack, OPTIONAL
588 IN VOID *Context OPTIONAL
589 )
590 /*++
591
592 Routine Description:
593 Usb Async Interrput Transfer
594
595 Arguments:
596 This - Indicates calling context.
597 DeviceEndpoint - The destination USB device endpoint to which the
598 device request is being sent.
599 IsNewTransfer - If TRUE, a new transfer will be submitted to USB
600 controller. If FALSE, the interrupt transfer is
601 deleted from the device's interrupt transfer queue.
602 PollingInterval - Indicates the periodic rate, in milliseconds, that
603 the transfer is to be executed.
604 DataLength - Specifies the length, in bytes, of the data to be
605 received from the USB device.
606 InterruptCallBack - The Callback function. This function is called if
607 the asynchronous interrupt transfer is completed.
608 Context - Passed to InterruptCallback
609 Returns:
610 EFI_SUCCESS
611 EFI_INVALID_PARAMETER
612 EFI_OUT_OF_RESOURCES
613
614 --*/
615 {
616 USB_IO_DEVICE *UsbIoDev;
617 UINTN MaxPacketLength;
618 UINT8 DataToggle;
619 EFI_STATUS RetStatus;
620 USB_IO_CONTROLLER_DEVICE *UsbIoController;
621 ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
622
623 //
624 // Check endpoint
625 //
626 if ((DeviceEndpoint & 0x7F) == 0) {
627 return EFI_INVALID_PARAMETER;
628 }
629
630 if ((DeviceEndpoint & 0x7F) > 15) {
631 return EFI_INVALID_PARAMETER;
632 }
633
634 EndpointListEntry = FindEndPointListEntry (
635 This,
636 DeviceEndpoint
637 );
638
639 if (EndpointListEntry == NULL) {
640 return EFI_INVALID_PARAMETER;
641 }
642
643 if ((EndpointListEntry->EndpointDescriptor.Attributes & 0x03) != 0x03) {
644 return EFI_INVALID_PARAMETER;
645 }
646
647 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
648 UsbIoDev = UsbIoController->UsbDevice;
649
650 if (!IsNewTransfer) {
651 //
652 // Delete this transfer
653 //
654 UsbVirtualHcAsyncInterruptTransfer (
655 UsbIoDev->BusController,
656 UsbIoDev->DeviceAddress,
657 DeviceEndpoint,
658 UsbIoDev->DeviceSpeed,
659 0,
660 FALSE,
661 &DataToggle,
662 PollingInterval,
663 DataLength,
664 UsbIoDev->Translator,
665 NULL,
666 NULL
667 );
668
669 //
670 // We need to store the toggle value
671 //
672 SetDataToggleBit (
673 This,
674 DeviceEndpoint,
675 DataToggle
676 );
677
678 return EFI_SUCCESS;
679 }
680
681 GetDeviceEndPointMaxPacketLength (
682 This,
683 DeviceEndpoint,
684 &MaxPacketLength
685 );
686
687 GetDataToggleBit (
688 This,
689 DeviceEndpoint,
690 &DataToggle
691 );
692
693 RetStatus = UsbVirtualHcAsyncInterruptTransfer (
694 UsbIoDev->BusController,
695 UsbIoDev->DeviceAddress,
696 DeviceEndpoint,
697 UsbIoDev->DeviceSpeed,
698 MaxPacketLength,
699 TRUE,
700 &DataToggle,
701 PollingInterval,
702 DataLength,
703 UsbIoDev->Translator,
704 InterruptCallBack,
705 Context
706 );
707
708 return RetStatus;
709 }
710
711 STATIC
712 EFI_STATUS
713 EFIAPI
714 UsbIsochronousTransfer (
715 IN EFI_USB_IO_PROTOCOL *This,
716 IN UINT8 DeviceEndpoint,
717 IN OUT VOID *Data,
718 IN UINTN DataLength,
719 OUT UINT32 *Status
720 )
721 /*++
722
723 Routine Description:
724 Usb Isochronous Transfer
725
726 Arguments:
727 This - Indicates calling context.
728 DeviceEndpoint - The destination USB device endpoint to which the
729 device request is being sent.
730 Data - A pointer to the buffer of data that will be
731 transmitted to USB device or received from USB device.
732 DataLength - The size, in bytes, of the data buffer specified by
733 Data.
734 Status - This parameter indicates the USB transfer status.
735
736 Returns:
737 EFI_SUCCESS
738 EFI_INVALID_PARAMETER
739 EFI_OUT_OF_RESOURCES
740 EFI_TIMEOUT
741 EFI_DEVICE_ERROR
742 EFI_UNSUPPORTED
743 --*/
744 {
745 //
746 // Currently we don't support this transfer
747 //
748 return EFI_UNSUPPORTED;
749 }
750
751 STATIC
752 EFI_STATUS
753 EFIAPI
754 UsbAsyncIsochronousTransfer (
755 IN EFI_USB_IO_PROTOCOL *This,
756 IN UINT8 DeviceEndpoint,
757 IN OUT VOID *Data,
758 IN UINTN DataLength,
759 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
760 IN VOID *Context OPTIONAL
761 )
762 /*++
763
764 Routine Description:
765
766 Usb Async Isochronous Transfer
767
768 Arguments:
769
770 This - EFI_USB_IO_PROTOCOL
771 DeviceEndpoint - DeviceEndpoint number
772 Data - Data to transfer
773 DataLength - DataLength
774 IsochronousCallBack - Isochronous CallBack function
775 Context - Passed to IsochronousCallBack function
776 Returns:
777
778 EFI_UNSUPPORTED - Unsupported now
779
780 --*/
781 {
782 //
783 // Currently we don't support this transfer
784 //
785 return EFI_UNSUPPORTED;
786 }
787 //
788 // Here is new definitions
789 //
790 STATIC
791 EFI_STATUS
792 EFIAPI
793 UsbGetDeviceDescriptor (
794 IN EFI_USB_IO_PROTOCOL *This,
795 OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor
796 )
797 /*++
798
799 Routine Description:
800 Retrieves the USB Device Descriptor.
801
802 Arguments:
803 This - Indicates the calling context.
804 DeviceDescriptor - A pointer to the caller allocated USB Device
805 Descriptor.
806
807 Returns:
808 EFI_SUCCESS
809 EFI_INVALID_PARAMETER
810 EFI_NOT_FOUND
811
812 --*/
813 {
814 USB_IO_CONTROLLER_DEVICE *UsbIoController;
815 USB_IO_DEVICE *UsbIoDev;
816
817 //
818 // This function just wrapps UsbGetDeviceDescriptor.
819 //
820
821 if (DeviceDescriptor == NULL) {
822 return EFI_INVALID_PARAMETER;
823 }
824
825 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
826 UsbIoDev = UsbIoController->UsbDevice;
827
828 if (!UsbIoDev->IsConfigured) {
829 return EFI_NOT_FOUND;
830 }
831
832 CopyMem (
833 DeviceDescriptor,
834 &UsbIoDev->DeviceDescriptor,
835 sizeof (EFI_USB_DEVICE_DESCRIPTOR)
836 );
837
838 return EFI_SUCCESS;
839 }
840
841 STATIC
842 EFI_STATUS
843 EFIAPI
844 UsbGetActiveConfigDescriptor (
845 IN EFI_USB_IO_PROTOCOL *This,
846 OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor
847 )
848 /*++
849
850 Routine Description:
851 Retrieves the current USB configuration Descriptor.
852
853 Arguments:
854 This - Indicates the calling context.
855 ConfigurationDescriptor - A pointer to the caller allocated USB active
856 Configuration Descriptor.
857
858 Returns:
859 EFI_SUCCESS
860 EFI_INVALID_PARAMETER
861 EFI_NOT_FOUND
862
863 --*/
864 {
865 USB_IO_DEVICE *UsbIoDev;
866 USB_IO_CONTROLLER_DEVICE *UsbIoController;
867
868 //
869 // This function just wrapps UsbGetActiveConfigDescriptor.
870 //
871 if (ConfigurationDescriptor == NULL) {
872 return EFI_INVALID_PARAMETER;
873 }
874
875 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
876 UsbIoDev = UsbIoController->UsbDevice;
877
878 if (!UsbIoDev->IsConfigured) {
879 return EFI_NOT_FOUND;
880 }
881
882 CopyMem (
883 ConfigurationDescriptor,
884 &(UsbIoDev->ActiveConfig->CongfigDescriptor),
885 sizeof (EFI_USB_CONFIG_DESCRIPTOR)
886 );
887
888 return EFI_SUCCESS;
889 }
890
891 STATIC
892 EFI_STATUS
893 EFIAPI
894 UsbGetInterfaceDescriptor (
895 IN EFI_USB_IO_PROTOCOL *This,
896 OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor
897 )
898 /*++
899
900 Routine Description:
901 Retrieves the interface Descriptor for that controller.
902
903 Arguments:
904 This - Indicates the calling context.
905 InterfaceDescriptor - A pointer to the caller allocated USB interface
906 Descriptor.
907
908 Returns:
909 EFI_SUCCESS
910 EFI_INVALID_PARAMETER
911 EFI_NOT_FOUND
912
913 --*/
914 {
915 INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;
916
917 if (InterfaceDescriptor == NULL) {
918 return EFI_INVALID_PARAMETER;
919 }
920
921 InterfaceListEntry = FindInterfaceListEntry (This);
922
923 if (InterfaceListEntry == NULL) {
924 return EFI_NOT_FOUND;
925 }
926
927 CopyMem (
928 InterfaceDescriptor,
929 &(InterfaceListEntry->InterfaceDescriptor),
930 sizeof (EFI_USB_INTERFACE_DESCRIPTOR)
931 );
932
933 return EFI_SUCCESS;
934 }
935
936 STATIC
937 EFI_STATUS
938 EFIAPI
939 UsbGetEndpointDescriptor (
940 IN EFI_USB_IO_PROTOCOL *This,
941 IN UINT8 EndpointIndex,
942 OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor
943 )
944 /*++
945
946 Routine Description:
947 Retrieves the endpoint Descriptor for a given endpoint.
948
949 Arguments:
950 This - Indicates the calling context.
951 EndpointIndex - Indicates which endpoint descriptor to retrieve.
952 The valid range is 0..15.
953 EndpointDescriptor - A pointer to the caller allocated USB Endpoint
954 Descriptor of a USB controller.
955
956 Returns:
957 EFI_SUCCESS - The endpoint descriptor was retrieved successfully.
958 EFI_INVALID_PARAMETER - EndpointIndex is not valid.
959 - EndpointDescriptor is NULL.
960 EFI_NOT_FOUND - The endpoint descriptor cannot be found.
961 The device may not be correctly configured.
962
963 --*/
964 {
965 INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;
966 LIST_ENTRY *EndpointListHead;
967 ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
968
969 if (EndpointDescriptor == NULL) {
970 return EFI_INVALID_PARAMETER;
971 }
972
973 if (EndpointIndex > 15) {
974 return EFI_INVALID_PARAMETER;
975 }
976
977 InterfaceListEntry = FindInterfaceListEntry (This);
978
979 if (InterfaceListEntry == NULL) {
980 return EFI_NOT_FOUND;
981 }
982
983 EndpointListHead = (LIST_ENTRY *) (&InterfaceListEntry->EndpointDescListHead);
984 EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListHead->ForwardLink);
985
986 if (EndpointIndex >= InterfaceListEntry->InterfaceDescriptor.NumEndpoints) {
987 return EFI_NOT_FOUND;
988 }
989 //
990 // Loop all endpoint descriptor to get match one.
991 //
992 while (EndpointIndex != 0) {
993 EndpointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointListEntry->Link.ForwardLink);
994 EndpointIndex--;
995 }
996
997 CopyMem (
998 EndpointDescriptor,
999 &EndpointListEntry->EndpointDescriptor,
1000 sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)
1001 );
1002
1003 return EFI_SUCCESS;
1004 }
1005
1006 STATIC
1007 EFI_STATUS
1008 EFIAPI
1009 UsbGetSupportedLanguages (
1010 IN EFI_USB_IO_PROTOCOL *This,
1011 OUT UINT16 **LangIDTable,
1012 OUT UINT16 *TableSize
1013 )
1014 /*++
1015
1016 Routine Description:
1017 Get all the languages that the USB device supports
1018
1019 Arguments:
1020 This - Indicates the calling context.
1021 LangIDTable - Language ID for the string the caller wants to get.
1022 TableSize - The size, in bytes, of the table LangIDTable.
1023
1024 Returns:
1025 EFI_SUCCESS
1026 EFI_NOT_FOUND
1027
1028 --*/
1029 {
1030 USB_IO_DEVICE *UsbIoDev;
1031 USB_IO_CONTROLLER_DEVICE *UsbIoController;
1032 UINTN Index;
1033 BOOLEAN Found;
1034
1035 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
1036 UsbIoDev = UsbIoController->UsbDevice;
1037
1038 Found = FALSE;
1039 Index = 0;
1040 //
1041 // Loop language table
1042 //
1043 while (UsbIoDev->LangID[Index]) {
1044 Found = TRUE;
1045 Index++;
1046 }
1047
1048 if (!Found) {
1049 return EFI_NOT_FOUND;
1050 }
1051
1052 *LangIDTable = UsbIoDev->LangID;
1053 *TableSize = (UINT16) Index;
1054
1055 return EFI_SUCCESS;
1056 }
1057
1058 STATIC
1059 EFI_STATUS
1060 EFIAPI
1061 UsbGetStringDescriptor (
1062 IN EFI_USB_IO_PROTOCOL *This,
1063 IN UINT16 LangID,
1064 IN UINT8 StringIndex,
1065 OUT CHAR16 **String
1066 )
1067 /*++
1068
1069 Routine Description:
1070 Get a given string descriptor
1071
1072 Arguments:
1073 This - Indicates the calling context.
1074 LangID - The Language ID for the string being retrieved.
1075 StringIndex - The ID of the string being retrieved.
1076 String - A pointer to a buffer allocated by this function
1077 with AllocatePool() to store the string. If this
1078 function returns EFI_SUCCESS, it stores the string
1079 the caller wants to get. The caller should release
1080 the string buffer with FreePool() after the string
1081 is not used any more.
1082 Returns:
1083 EFI_SUCCESS
1084 EFI_NOT_FOUND
1085 EFI_OUT_OF_RESOURCES
1086 EFI_UNSUPPORTED
1087
1088 --*/
1089 {
1090 UINT32 Status;
1091 EFI_STATUS Result;
1092 EFI_USB_STRING_DESCRIPTOR *StrDescriptor;
1093 UINT8 *Buffer;
1094 CHAR16 *UsbString;
1095 UINT16 TempBuffer;
1096 USB_IO_DEVICE *UsbIoDev;
1097 UINT8 Index;
1098 BOOLEAN Found;
1099 USB_IO_CONTROLLER_DEVICE *UsbIoController;
1100
1101 if (StringIndex == 0) {
1102 return EFI_NOT_FOUND;
1103 }
1104 //
1105 // Search LanguageID, check if it is supported by this device
1106 //
1107 if (LangID == 0) {
1108 return EFI_NOT_FOUND;
1109 }
1110
1111 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
1112 UsbIoDev = UsbIoController->UsbDevice;
1113
1114 Found = FALSE;
1115 Index = 0;
1116 while (UsbIoDev->LangID[Index]) {
1117 if (UsbIoDev->LangID[Index] == LangID) {
1118 Found = TRUE;
1119 break;
1120 }
1121
1122 Index++;
1123 }
1124
1125 if (!Found) {
1126 return EFI_NOT_FOUND;
1127 }
1128 //
1129 // Get String Length
1130 //
1131 Result = UsbGetString (
1132 This,
1133 LangID,
1134 StringIndex,
1135 &TempBuffer,
1136 2,
1137 &Status
1138 );
1139 if (EFI_ERROR (Result)) {
1140 return EFI_NOT_FOUND;
1141 }
1142
1143 StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) &TempBuffer;
1144
1145 if (StrDescriptor->Length == 0) {
1146 return EFI_UNSUPPORTED;
1147 }
1148
1149 Buffer = AllocateZeroPool (StrDescriptor->Length);
1150 if (Buffer == NULL) {
1151 return EFI_OUT_OF_RESOURCES;
1152 }
1153
1154 Result = UsbGetString (
1155 This,
1156 LangID,
1157 StringIndex,
1158 Buffer,
1159 StrDescriptor->Length,
1160 &Status
1161 );
1162
1163 if (EFI_ERROR (Result)) {
1164 gBS->FreePool (Buffer);
1165 return EFI_NOT_FOUND;
1166 }
1167
1168 StrDescriptor = (EFI_USB_STRING_DESCRIPTOR *) Buffer;
1169
1170 //
1171 // UsbString is a UNICODE string
1172 //
1173 UsbString = AllocateZeroPool (StrDescriptor->Length);
1174 if (UsbString == NULL) {
1175 gBS->FreePool (Buffer);
1176 return EFI_OUT_OF_RESOURCES;
1177 }
1178
1179 CopyMem (
1180 (VOID *) UsbString,
1181 Buffer + 2,
1182 StrDescriptor->Length - 2
1183 );
1184
1185 *String = UsbString;
1186
1187 gBS->FreePool (Buffer);
1188
1189 return EFI_SUCCESS;
1190 }