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