|
| 1 | +// SPDX-License-Identifier: MIT OR Apache-2.0 |
| 2 | + |
| 3 | +use core::mem; |
| 4 | +use uefi::proto::usb::DeviceDescriptor; |
| 5 | +use uefi::proto::usb::io::{ControlTransfer, UsbIo}; |
| 6 | +use uefi::{Status, boot}; |
| 7 | + |
| 8 | +pub fn test() { |
| 9 | + info!("Testing USB I/O protocol"); |
| 10 | + |
| 11 | + let handles = boot::locate_handle_buffer(boot::SearchType::from_proto::<UsbIo>()) |
| 12 | + .expect("failed to acquire USB I/O handles"); |
| 13 | + |
| 14 | + for handle in handles.iter().copied() { |
| 15 | + let mut io = boot::open_protocol_exclusive::<UsbIo>(handle) |
| 16 | + .expect("failed to open USB I/O protocol"); |
| 17 | + |
| 18 | + let device = io |
| 19 | + .device_descriptor() |
| 20 | + .expect("failed to acquire USB device descriptor"); |
| 21 | + io.config_descriptor() |
| 22 | + .expect("failed to acquire USB config descriptor"); |
| 23 | + io.interface_descriptor() |
| 24 | + .expect("failed to acquire USB interface descriptor"); |
| 25 | + |
| 26 | + for endpoint_index in 0..16 { |
| 27 | + let result = io.endpoint_descriptor(endpoint_index); |
| 28 | + if result |
| 29 | + .as_ref() |
| 30 | + .is_err_and(|error| error.status() == Status::NOT_FOUND) |
| 31 | + { |
| 32 | + continue; |
| 33 | + } |
| 34 | + |
| 35 | + result.expect("failed to acquire USB endpoint descriptor"); |
| 36 | + } |
| 37 | + |
| 38 | + let supported_languages = io |
| 39 | + .supported_languages() |
| 40 | + .expect("failed to acquire supported language list"); |
| 41 | + let test_language = supported_languages[0]; |
| 42 | + |
| 43 | + for string_index in 0..=u8::MAX { |
| 44 | + let result = io.string_descriptor(test_language, string_index); |
| 45 | + if result |
| 46 | + .as_ref() |
| 47 | + .is_err_and(|error| error.status() == Status::NOT_FOUND) |
| 48 | + { |
| 49 | + continue; |
| 50 | + } |
| 51 | + |
| 52 | + result.expect("failed to acquire string descriptor"); |
| 53 | + } |
| 54 | + |
| 55 | + let mut buffer = [0u8; mem::size_of::<DeviceDescriptor>()]; |
| 56 | + |
| 57 | + io.control_transfer( |
| 58 | + 0b1000_0000, |
| 59 | + 6, |
| 60 | + 1u16 << 8, |
| 61 | + 0, |
| 62 | + ControlTransfer::DataIn(&mut buffer[..mem::size_of::<DeviceDescriptor>()]), |
| 63 | + 0, |
| 64 | + ) |
| 65 | + .expect("failed control transfer"); |
| 66 | + unsafe { |
| 67 | + assert_eq!( |
| 68 | + device, |
| 69 | + buffer.as_ptr().cast::<DeviceDescriptor>().read_unaligned() |
| 70 | + ) |
| 71 | + } |
| 72 | + } |
| 73 | +} |
0 commit comments