Allow usbhidd to run on multiple interfaces

This commit is contained in:
Jeremy Soller
2024-11-04 16:15:53 -07:00
parent 2975f93f30
commit 6ff633863e
3 changed files with 47 additions and 25 deletions
+18 -11
View File
@@ -205,19 +205,21 @@ fn main() {
.expect("Failed to get standard descriptors");
log::info!("{:X?}", desc);
let (conf_desc, conf_num, (if_desc, endpoint_num_opt, hid_desc)) =
let mut endp_count = 0;
let (conf_desc, conf_num, (if_desc, endp_desc_opt, hid_desc)) =
desc.config_descs
.iter()
.enumerate()
.find_map(|(conf_num, conf_desc)| {
let if_desc = conf_desc.interface_descs.iter().find_map(|if_desc| {
if if_desc.number == interface_num {
let endpoint_num_opt = if_desc.endpoints.iter().enumerate().find_map(
|(endpoint_i, endpoint)| {
if endpoint.ty() == EndpointTy::Interrupt
&& endpoint.direction() == EndpDirection::In
let endp_desc_opt = if_desc.endpoints.iter().find_map(
|endp_desc| {
endp_count += 1;
if endp_desc.ty() == EndpointTy::Interrupt
&& endp_desc.direction() == EndpDirection::In
{
Some(endpoint_i + 1)
Some((endp_count, endp_desc.clone()))
} else {
None
}
@@ -227,8 +229,9 @@ fn main() {
//TODO: should we do any filtering?
Some(hid_desc)
})?;
Some((if_desc.clone(), endpoint_num_opt, hid_desc))
Some((if_desc.clone(), endp_desc_opt, hid_desc))
} else {
endp_count += if_desc.endpoints.len();
None
}
})?;
@@ -268,17 +271,21 @@ fn main() {
let mut handler =
ReportHandler::new(&report_desc_bytes).expect("failed to parse report descriptor");
let mut report_buffer = vec![0u8; handler.total_byte_length];
let report_len = match endp_desc_opt {
Some((_endp_num, endp_desc)) => endp_desc.max_packet_size as usize,
None => handler.total_byte_length as usize,
};
let mut report_buffer = vec![0u8; report_len];
let report_ty = ReportTy::Input;
let report_id = 0;
let mut display =
File::open("/scheme/input/producer").expect("Failed to open orbital input socket");
let mut endpoint_opt = match endpoint_num_opt {
Some(endpoint_num) => match handle.open_endpoint(endpoint_num as u8) {
let mut endpoint_opt = match endp_desc_opt {
Some((endp_num, _endp_desc)) => match handle.open_endpoint(endp_num as u8) {
Ok(ok) => Some(ok),
Err(err) => {
log::warn!("failed to open endpoint {endpoint_num}: {err}");
log::warn!("failed to open endpoint {endp_num}: {err}");
None
}
},
+1 -2
View File
@@ -970,8 +970,7 @@ impl Xhci {
let drivers_usercfg: &DriversConfig = &DRIVERS_CONFIG;
//TODO: allow spawning on all interfaces (will require fixing port state)
for ifdesc in config_desc.interface_descs.iter().take(1) {
for ifdesc in config_desc.interface_descs.iter() {
if let Some(driver) = drivers_usercfg.drivers.iter().find(|driver| {
driver.class == ifdesc.class
&& driver
+28 -12
View File
@@ -912,19 +912,8 @@ impl Xhci {
) -> Result<chashmap::WriteGuard<'_, usize, super::PortState>> {
self.port_states.get_mut(&port).ok_or(Error::new(EBADF))
}
async fn configure_endpoints(&self, port: usize, json_buf: &[u8]) -> Result<()> {
let mut req: ConfigureEndpointsReq =
serde_json::from_slice(json_buf).or(Err(Error::new(EBADMSG)))?;
info!(
"Running configure endpoints command, at port {}, request: {:?}",
port, req
);
if req.interface_desc.is_some() != req.alternate_setting.is_some() {
return Err(Error::new(EBADMSG));
}
async fn configure_endpoints_once(&self, port: usize, req: &ConfigureEndpointsReq) -> Result<()> {
let (endp_desc_count, new_context_entries, configuration_value) = {
let mut port_state = self.port_states.get_mut(&port).ok_or(Error::new(EBADFD))?;
@@ -1144,6 +1133,8 @@ impl Xhci {
endp_ctx
.c
.write(u32::from(avg_trb_len) | (u32::from(max_esit_payload_lo) << 16));
log::info!("INITIALIZED ENDPOINT {}", endp_num);
}
{
@@ -1165,6 +1156,31 @@ impl Xhci {
// Tell the device about this configuration.
self.set_configuration(port, configuration_value).await?;
Ok(())
}
async fn configure_endpoints(&self, port: usize, json_buf: &[u8]) -> Result<()> {
let mut req: ConfigureEndpointsReq =
serde_json::from_slice(json_buf).or(Err(Error::new(EBADMSG)))?;
info!(
"Running configure endpoints command, at port {}, request: {:?}",
port, req
);
if req.interface_desc.is_some() != req.alternate_setting.is_some() {
return Err(Error::new(EBADMSG));
}
let already_configured = {
let port_state = self.port_states.get(&port).ok_or(Error::new(EBADFD))?;
port_state.cfg_idx == Some(req.config_desc)
};
if ! already_configured {
self.configure_endpoints_once(port, &req).await?;
}
if let Some(interface_num) = req.interface_desc {
if let Some(alternate_setting) = req.alternate_setting {
self.set_interface(port, interface_num, alternate_setting)