diff --git a/local/recipes/system/redbear-ecmd/source/src/main.rs b/local/recipes/system/redbear-ecmd/source/src/main.rs index ead3d9ac16..0c1c2968c3 100644 --- a/local/recipes/system/redbear-ecmd/source/src/main.rs +++ b/local/recipes/system/redbear-ecmd/source/src/main.rs @@ -110,29 +110,35 @@ fn main() { let data_iface = data_iface.expect("No CDC ECM data interface found"); // Find bulk IN + bulk OUT on the data interface, and optional - // interrupt endpoint on the control interface. + // interrupt endpoint on the control interface. xhcid keys endpoints + // by GLOBAL index across all interfaces of the configuration (see + // xhcid PortState::get_endp_desc / endpoint_states) — the USB + // endpoint address number only coincides with that index when the + // device's addresses are sequential in enumeration order, so count + // endpoints in configuration order instead. let mut bulk_in_num = 0u8; let mut bulk_out_num = 0u8; let mut int_num = 0u8; for conf_desc in desc.config_descs.iter() { + // xhcid indexes endpoints within the selected configuration only; + // reset the counter per config and keep only the selected one. + let mut config_num = 0u8; for ifd in conf_desc.interface_descs.iter() { - if ifd.number == data_iface { - for ep in ifd.endpoints.iter() { - if ep.attributes & 0x03 == 0x02 { // bulk transfer type - match ep.direction() { - EndpDirection::In => bulk_in_num = ep.address & 0x0F, - EndpDirection::Out => bulk_out_num = ep.address & 0x0F, - _ => {} - } + for ep in ifd.endpoints.iter() { + config_num += 1; + if conf_desc.configuration_value != conf_val { + continue; + } + if ifd.number == data_iface && ep.attributes & 0x03 == 0x02 { // bulk transfer type + match ep.direction() { + EndpDirection::In => bulk_in_num = config_num, + EndpDirection::Out => bulk_out_num = config_num, + _ => {} } } - } - if ifd.number == ctrl_iface { - for ep in ifd.endpoints.iter() { - if ep.attributes & 0x03 == 0x03 { // interrupt transfer type - int_num = ep.address & 0x0F; - } + if ifd.number == ctrl_iface && ep.attributes & 0x03 == 0x03 { // interrupt transfer type + int_num = config_num; } } } diff --git a/local/recipes/system/redbear-usbaudiod/source/src/main.rs b/local/recipes/system/redbear-usbaudiod/source/src/main.rs index 3dc081faf3..05c9ed1bd5 100644 --- a/local/recipes/system/redbear-usbaudiod/source/src/main.rs +++ b/local/recipes/system/redbear-usbaudiod/source/src/main.rs @@ -188,24 +188,34 @@ fn main() { return; } - // Find isoch endpoints on the streaming interface + // Find isoch endpoints on the streaming interface. xhcid keys + // endpoints by GLOBAL index across all interfaces of the + // configuration (see xhcid PortState::get_endp_desc / + // endpoint_states) — the USB endpoint address number only coincides + // with that index when the device's addresses are sequential in + // enumeration order, so count endpoints in configuration order. let mut isoch_in_num = 0u8; let mut isoch_out_num = 0u8; let mut max_pkt_size = 0u16; for conf_desc in desc.config_descs.iter() { + // xhcid indexes endpoints within the selected configuration only; + // reset the counter per config and keep only the selected one. + let mut config_num = 0u8; for ifd in conf_desc.interface_descs.iter() { - if ifd.number == as_iface { - for ep in ifd.endpoints.iter() { - if ep.attributes & 0x03 == 0x01 { // isoch transfer type - if ep.max_packet_size > max_pkt_size { - max_pkt_size = ep.max_packet_size; - } - match ep.direction() { - EndpDirection::In => isoch_in_num = ep.address & 0x0F, - EndpDirection::Out => isoch_out_num = ep.address & 0x0F, - _ => {} - } + for ep in ifd.endpoints.iter() { + config_num += 1; + if conf_desc.configuration_value != conf_val { + continue; + } + if ifd.number == as_iface && ep.attributes & 0x03 == 0x01 { // isoch transfer type + if ep.max_packet_size > max_pkt_size { + max_pkt_size = ep.max_packet_size; + } + match ep.direction() { + EndpDirection::In => isoch_in_num = config_num, + EndpDirection::Out => isoch_out_num = config_num, + _ => {} } } }