diff options
author | Brian Cully <bjc@kublai.com> | 2019-08-10 14:08:53 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-08-10 14:08:53 -0400 |
commit | ba894eb475fbf1c5e744531057ed63ffcb1e8afc (patch) | |
tree | 0d3a554e61276ce93b8f4f98e567022190efbdaf /src | |
parent | be7c1fb0a1070298a2db0fa07b6430f4506e5c3d (diff) | |
download | bootkbd-ba894eb475fbf1c5e744531057ed63ffcb1e8afc.tar.gz bootkbd-ba894eb475fbf1c5e744531057ed63ffcb1e8afc.zip |
Store max packet sizes from device and endpoint descriptors.
Device's bMaxPacketSize is used for the control endpoint 0, otherwise
the endpoint max packet sizes come from the endpoint descriptors.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 67 |
1 files changed, 45 insertions, 22 deletions
@@ -2,7 +2,7 @@ #![no_std] -use log::{debug, error, info}; +use log::{self, debug, error, info, trace, LevelFilter}; use usb_host::{ ConfigurationDescriptor, DescriptorType, DeviceDescriptor, Direction, Driver, DriverError, Endpoint, EndpointDescriptor, InterfaceDescriptor, RequestCode, RequestDirection, RequestKind, @@ -56,10 +56,10 @@ where true } - fn add_device(&mut self, _device: DeviceDescriptor, address: u8) -> Result<(), DriverError> { + fn add_device(&mut self, device: DeviceDescriptor, address: u8) -> Result<(), DriverError> { for i in 0..self.devices.len() { if self.devices[i].is_none() { - self.devices[i] = Some(Device::new(address)); + self.devices[i] = Some(Device::new(address, device.b_max_packet_size)); return Ok(()); } } @@ -109,7 +109,7 @@ struct Device { } impl Device { - fn new(addr: u8) -> Self { + fn new(addr: u8, max_packet_size: u8) -> Self { let endpoints: [Option<EP>; MAX_ENDPOINTS] = { let mut eps: [MaybeUninit<Option<EP>>; MAX_ENDPOINTS] = unsafe { mem::MaybeUninit::uninit().assume_init() }; @@ -121,7 +121,13 @@ impl Device { Self { addr: addr, - ep0: EP::new(addr, 0, TransferType::Control, Direction::In), + ep0: EP::new( + addr, + 0, + TransferType::Control, + Direction::In, + max_packet_size as u16, + ), endpoints: endpoints, state: DeviceState::Addressed, } @@ -189,7 +195,8 @@ impl Device { assert!(len == mem::size_of::<ConfigurationDescriptor>()); let conf_desc = unsafe { conf_desc.assume_init() }; - if (conf_desc.w_total_length as usize) < CONFIG_BUFFER_LEN { + if (conf_desc.w_total_length as usize) > CONFIG_BUFFER_LEN { + trace!("config descriptor: {:?}", conf_desc); return Err(TransferError::Permanent("config descriptor too large")); } @@ -211,18 +218,15 @@ impl Device { Some(&mut tmp), )?; assert!(len == conf_desc.w_total_length as usize); - let ep = match ep_for_bootkbd(&tmp) { - Ok(Some(n)) => n & 0x7f, - Ok(None) => Err(TransferError::Permanent("no boot keyboard found"))?, - Err(e) => Err(TransferError::Permanent(e))?, - }; - info!("Boot keyboard found on endpoint {}", ep); + let ep = ep_for_bootkbd(&tmp).expect("no boot keyboard found"); + info!("Boot keyboard found on {:?}", ep); self.endpoints[0] = Some(EP::new( self.addr, - ep, + ep.b_endpoint_address & 0x7f, TransferType::Interrupt, Direction::In, + ep.w_max_packet_size, )); // TODO: browse configs and pick the "best" one. But @@ -278,6 +282,9 @@ impl Device { Some(&mut report), )?; + // If we made it this far, thins should be ok, so + // throttle the logging. + log::set_max_level(LevelFilter::Info); self.state = DeviceState::Running } @@ -310,17 +317,25 @@ struct EP { num: u8, transfer_type: TransferType, direction: Direction, + max_packet_size: u16, in_toggle: bool, out_toggle: bool, } impl EP { - fn new(addr: u8, num: u8, transfer_type: TransferType, direction: Direction) -> Self { + fn new( + addr: u8, + num: u8, + transfer_type: TransferType, + direction: Direction, + max_packet_size: u16, + ) -> Self { Self { addr: addr, num: num, transfer_type: transfer_type, direction: direction, + max_packet_size: max_packet_size, in_toggle: false, out_toggle: false, } @@ -345,7 +360,7 @@ impl Endpoint for EP { } fn max_packet_size(&self) -> u16 { - 8 + self.max_packet_size } fn in_toggle(&self) -> bool { @@ -384,8 +399,8 @@ impl<'a> From<&'a [u8]> for DescriptorParser<'a> { } } -impl DescriptorParser<'_> { - fn next(&mut self) -> Option<Descriptor> { +impl<'a> DescriptorParser<'a> { + fn next<'b>(&'b mut self) -> Option<Descriptor<'a>> { if self.pos == self.buf.len() { return None; } @@ -434,7 +449,7 @@ impl DescriptorParser<'_> { } } -fn ep_for_bootkbd(buf: &[u8]) -> Result<Option<u8>, &'static str> { +fn ep_for_bootkbd<'a>(buf: &'a [u8]) -> Option<&'a EndpointDescriptor> { let mut parser = DescriptorParser::from(buf); let mut interface_found = false; while let Some(desc) = parser.next() { @@ -444,11 +459,11 @@ fn ep_for_bootkbd(buf: &[u8]) -> Result<Option<u8>, &'static str> { && idesc.b_interface_protocol == 0x01; } else if let Descriptor::Endpoint(edesc) = desc { if interface_found { - return Ok(Some(edesc.b_endpoint_address)); + return Some(edesc); } } } - Ok(None) + None } #[cfg(test)] @@ -582,7 +597,15 @@ mod test { 0x08, 0x00, 0x0a, ]; - let n = ep_for_bootkbd(raw).expect("Looking for endpoint"); - assert_eq!(n, Some(0x81)); + let got = ep_for_bootkbd(raw).expect("Looking for endpoint"); + let want = EndpointDescriptor { + b_length: 7, + b_descriptor_type: DescriptorType::Endpoint, + b_endpoint_address: 0x81, + bm_attributes: 0x03, + w_max_packet_size: 0x08, + b_interval: 0x0a, + }; + assert_eq!(*got, want); } } |