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