From 08616920d61a8a99107363d34895a0e395df6fcf Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 29 Mar 2020 13:49:57 +0200 Subject: [PATCH] Get descriptor fetching working. --- xhcid/src/xhci/irq_reactor.rs | 4 +-- xhcid/src/xhci/mod.rs | 51 ++++++++++++++++++++++------------- xhcid/src/xhci/scheme.rs | 41 +++++++++++++++++----------- xhcid/src/xhci/trb.rs | 6 +++-- 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/xhcid/src/xhci/irq_reactor.rs b/xhcid/src/xhci/irq_reactor.rs index 61d7f548a7..0abc6a2a9b 100644 --- a/xhcid/src/xhci/irq_reactor.rs +++ b/xhcid/src/xhci/irq_reactor.rs @@ -406,7 +406,7 @@ impl Xhci { Some(function(ring_ref)) } - pub fn next_transfer_event_trb(&self, ring_id: RingId, trb: &Trb) -> impl Future + Send + Sync + 'static { + pub fn next_transfer_event_trb(&self, ring_id: RingId, ring: &Ring, trb: &Trb) -> impl Future + Send + Sync + 'static { if ! trb.is_transfer_trb() { panic!("Invalid TRB type given to next_transfer_event_trb(): {} (TRB {:?}. Expected transfer TRB.", trb.trb_type(), trb) } @@ -418,7 +418,7 @@ impl Xhci { is_isoch_or_vf, state_kind: StateKind::Transfer { ring_id, - phys_ptr: self.with_ring(ring_id, |ring| ring.trb_phys_ptr(trb)).unwrap(), + phys_ptr: ring.trb_phys_ptr(trb), }, message: Arc::new(Mutex::new(None)), }, diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index b81f0b38bf..8e11e56781 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -12,7 +12,7 @@ use std::{mem, process, slice, sync::atomic, task, thread}; use chashmap::CHashMap; use crossbeam_channel::{Receiver, Sender}; use serde::Deserialize; -use syscall::error::{Error, Result, EBADF, EBADMSG, ENOENT}; +use syscall::error::{Error, Result, EBADF, EBADMSG, ENOENT, EIO}; use syscall::flag::O_RDONLY; use syscall::io::{Dma, Io}; @@ -93,10 +93,16 @@ impl MsixInfo { impl Xhci { /// Gets descriptors, before the port state is initiated. - async fn get_desc_raw(&self, port: usize, slot: u8, kind: usb::DescriptorKind, index: u8, ring: &mut Ring, desc: &mut Dma) -> Result<()> { + async fn get_desc_raw(&self, port: usize, slot: u8, kind: usb::DescriptorKind, index: u8, desc: &mut Dma) -> Result<()> { + println!("A"); let len = mem::size_of::(); let future = { + println!("B"); + let mut port_state = self.port_states.get_mut(&port).ok_or(Error::new(ENOENT))?; + let ring = port_state.endpoint_states.get_mut(&0).ok_or(Error::new(EIO))?.ring().expect("no ring for the default control pipe"); + println!("C"); + let (cmd, cycle) = ring.next(); cmd.setup( usb::Setup::get_descriptor(kind, index, 0, len as u16), @@ -107,45 +113,52 @@ impl Xhci { let (cmd, cycle) = ring.next(); cmd.data(desc.physical(), len as u16, true, cycle); - let (cmd, cycle) = ring.next(); + let last_index = ring.next_index(); + let (cmd, cycle) = (&mut ring.trbs[last_index], ring.cycle); cmd.status(0, true, true, false, false, cycle); - self.next_transfer_event_trb(RingId::default_control_pipe(port as u8), &cmd) + println!("D"); + self.next_transfer_event_trb(RingId::default_control_pipe(port as u8), &ring, &ring.trbs[last_index]) }; + println!("E"); self.dbs.lock().unwrap()[usize::from(slot)].write(Self::def_control_endp_doorbell()); + println!("F"); let trbs = future.await; let event_trb = trbs.event_trb; let status_trb = trbs.src_trb.unwrap(); + println!("G"); self::scheme::handle_transfer_event_trb("GET_DESC", &event_trb, &status_trb)?; + println!("H"); self.event_handler_finished(); + println!("I"); Ok(()) } - async fn fetch_dev_desc(&self, port: usize, slot: u8, ring: &mut Ring) -> Result { + async fn fetch_dev_desc(&self, port: usize, slot: u8) -> Result { let mut desc = Dma::::zeroed()?; - self.get_desc_raw(port, slot, usb::DescriptorKind::Device, 0, ring, &mut desc).await?; + self.get_desc_raw(port, slot, usb::DescriptorKind::Device, 0, &mut desc).await?; Ok(*desc) } - async fn fetch_config_desc(&self, port: usize, slot: u8, ring: &mut Ring, config: u8) -> Result<(usb::ConfigDescriptor, [u8; 4087])> { + async fn fetch_config_desc(&self, port: usize, slot: u8, config: u8) -> Result<(usb::ConfigDescriptor, [u8; 4087])> { let mut desc = Dma::<(usb::ConfigDescriptor, [u8; 4087])>::zeroed()?; - self.get_desc_raw(port, slot, usb::DescriptorKind::Configuration, config, ring, &mut desc).await?; + self.get_desc_raw(port, slot, usb::DescriptorKind::Configuration, config, &mut desc).await?; Ok(*desc) } - async fn fetch_bos_desc(&self, port: usize, slot: u8, ring: &mut Ring) -> Result<(usb::BosDescriptor, [u8; 4087])> { + async fn fetch_bos_desc(&self, port: usize, slot: u8) -> Result<(usb::BosDescriptor, [u8; 4087])> { let mut desc = Dma::<(usb::BosDescriptor, [u8; 4087])>::zeroed()?; - self.get_desc_raw(port, slot, usb::DescriptorKind::BinaryObjectStorage, 0, ring, &mut desc).await?; + self.get_desc_raw(port, slot, usb::DescriptorKind::BinaryObjectStorage, 0, &mut desc).await?; Ok(*desc) } - async fn fetch_string_desc(&self, port: usize, slot: u8, ring: &mut Ring, index: u8) -> Result { + async fn fetch_string_desc(&self, port: usize, slot: u8, index: u8) -> Result { let mut sdesc = Dma::<(u8, u8, [u16; 127])>::zeroed()?; - self.get_desc_raw(port, slot, usb::DescriptorKind::String, index, ring, &mut sdesc).await?; + self.get_desc_raw(port, slot, usb::DescriptorKind::String, index, &mut sdesc).await?; let len = sdesc.0 as usize; if len > 2 { @@ -489,14 +502,16 @@ impl Xhci { )) .collect::>(), }; + self.port_states.insert(i, port_state); - let ring = port_state.endpoint_states.get_mut(&0).unwrap().ring().unwrap(); - - let dev_desc = self.get_desc(i, slot, ring).await?; - port_state.dev_desc = Some(dev_desc); - + println!("pre get desc"); + let dev_desc = self.get_desc(i, slot).await?; + println!("post get desc"); + self.port_states.get_mut(&i).unwrap().dev_desc = Some(dev_desc); { + let mut port_state = self.port_states.get_mut(&i).unwrap(); + let mut input = port_state.input_context.lock().unwrap(); let dev_desc = port_state.dev_desc.as_ref().unwrap(); @@ -508,7 +523,6 @@ impl Xhci { Err(err) => println!("Failed to spawn driver for port {}: `{}`", i, err), }*/ - self.port_states.insert(i, port_state); } } @@ -643,6 +657,7 @@ impl Xhci { if event_trb.completion_code() != TrbCompletionCode::Success as u8 { println!("Failed to address device at slot {} (port {})", slot, i); } + self.event_handler_finished(); Ok(ring) } diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index c722986af7..3709b18845 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -192,7 +192,6 @@ impl Xhci { &self, port_id: usize, slot: u8, - ring: &mut Ring, desc: usb::InterfaceDescriptor, endps: impl IntoIterator, hid_descs: impl IntoIterator, @@ -201,7 +200,7 @@ impl Xhci { alternate_setting: desc.alternate_setting, class: desc.class, interface_str: if desc.interface_str > 0 { - Some(self.fetch_string_desc(port_id, slot, ring, desc.interface_str).await?) + Some(self.fetch_string_desc(port_id, slot, desc.interface_str).await?) } else { None }, @@ -284,7 +283,8 @@ impl Xhci { } } - let (cmd, cycle) = ring.next(); + let last_index = ring.next_index(); + let (cmd, cycle) = (&mut ring.trbs[last_index], ring.cycle); let interrupter = 0; let ioc = true; @@ -292,7 +292,7 @@ impl Xhci { let ent = false; cmd.status(interrupter, tk == TransferKind::In, ioc, ch, ent, cycle); - self.next_transfer_event_trb(RingId::default_control_pipe(port_num as u8), cmd) + self.next_transfer_event_trb(RingId::default_control_pipe(port_num as u8), ring, &ring.trbs[last_index]) }; self.dbs.lock().unwrap()[usize::from(slot)].write(Self::def_control_endp_doorbell()); @@ -352,11 +352,12 @@ impl Xhci { }; let future = loop { - let (trb, cycle) = ring.next(); + let last_index = ring.next_index(); + let (trb, cycle) = (&mut ring.trbs[last_index], ring.cycle); match d(trb, cycle) { ControlFlow::Break => { - break self.next_transfer_event_trb(super::irq_reactor::RingId { port: port_num as u8, endpoint_num: endp_num, stream_id }, &trb); + break self.next_transfer_event_trb(super::irq_reactor::RingId { port: port_num as u8, endpoint_num: endp_num, stream_id }, ring, &ring.trbs[last_index]); } ControlFlow::Continue => continue, } @@ -923,35 +924,43 @@ impl Xhci { &self, port_id: usize, slot: u8, - ring: &mut Ring, ) -> Result { + println!("Checkpoint 1"); let ports = self.ports.lock().unwrap(); let port = ports.get(port_id).ok_or(Error::new(ENOENT))?; if !port.flags().contains(port::PortFlags::PORT_CCS) { return Err(Error::new(ENOENT)); } - let raw_dd = self.fetch_dev_desc(port_id, slot, ring).await?; + println!("Checkpoint 2"); + let raw_dd = self.fetch_dev_desc(port_id, slot).await?; + println!("Checkpoint 3"); let (manufacturer_str, product_str, serial_str) = ( if raw_dd.manufacturer_str > 0 { - Some(self.fetch_string_desc(port_id, slot, ring, raw_dd.manufacturer_str).await?) + println!("Checkpoint 4a"); + Some(self.fetch_string_desc(port_id, slot, raw_dd.manufacturer_str).await?) } else { None }, if raw_dd.product_str > 0 { - Some(self.fetch_string_desc(port_id, slot, ring, raw_dd.product_str).await?) + println!("Checkpoint 4b"); + Some(self.fetch_string_desc(port_id, slot, raw_dd.product_str).await?) } else { None }, if raw_dd.serial_str > 0 { - Some(self.fetch_string_desc(port_id, slot, ring, raw_dd.serial_str).await?) + println!("Checkpoint 4c"); + Some(self.fetch_string_desc(port_id, slot, raw_dd.serial_str).await?) } else { None }, ); - let (bos_desc, bos_data) = self.fetch_bos_desc(port_id, slot, ring).await?; + println!("Checkpoint 5"); + let (bos_desc, bos_data) = self.fetch_bos_desc(port_id, slot).await?; + println!("Checkpoint 6"); + let supports_superspeed = usb::bos_capability_descs(bos_desc, &bos_data).any(|desc| desc.is_superspeed()); let supports_superspeedplus = @@ -960,7 +969,9 @@ impl Xhci { let mut config_descs = SmallVec::new(); for index in 0..raw_dd.configurations { - let (desc, data) = self.fetch_config_desc(port_id, slot, ring, index).await?; + println!("Checkpoint 7: {}", index); + let (desc, data) = self.fetch_config_desc(port_id, slot, index).await?; + println!("Checkpoint 8: {}", index); let extra_length = desc.total_length as usize - mem::size_of_val(&desc); let data = &data[..extra_length]; @@ -1010,7 +1021,7 @@ impl Xhci { endpoints.push(endp); } - interface_descs.push(self.new_if_desc(port_id, slot, ring, idesc, endpoints, hid_descs).await?); + interface_descs.push(self.new_if_desc(port_id, slot, idesc, endpoints, hid_descs).await?); } else { // TODO break; @@ -1020,7 +1031,7 @@ impl Xhci { config_descs.push(ConfDesc { kind: desc.kind, configuration: if desc.configuration_str > 0 { - Some(self.fetch_string_desc(port_id, slot, ring, desc.configuration_str).await?) + Some(self.fetch_string_desc(port_id, slot, desc.configuration_str).await?) } else { None }, diff --git a/xhcid/src/xhci/trb.rs b/xhcid/src/xhci/trb.rs index 1a91800bbf..a26a28f626 100644 --- a/xhcid/src/xhci/trb.rs +++ b/xhcid/src/xhci/trb.rs @@ -378,9 +378,11 @@ impl Trb { self.set( 0, u32::from(interrupter) << 22, - ((input as u32) << 16) + (u32::from(input) << 16) | ((TrbType::StatusStage as u32) << 10) - | (1 << 5) + | (u32::from(ioc) << 5) + | (u32::from(ch) << 4) + | (u32::from(ent) << 1) | (cycle as u32), ); }