aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-08-10 14:08:53 -0400
committerBrian Cully <bjc@kublai.com>2019-08-10 14:08:53 -0400
commitba894eb475fbf1c5e744531057ed63ffcb1e8afc (patch)
tree0d3a554e61276ce93b8f4f98e567022190efbdaf
parentbe7c1fb0a1070298a2db0fa07b6430f4506e5c3d (diff)
downloadbootkbd-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.
-rw-r--r--src/lib.rs67
1 files changed, 45 insertions, 22 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b9f17e4..ec82ea2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
}
}