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