Allow usbhidd to run on multiple interfaces
This commit is contained in:
+18
-11
@@ -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
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user