Get descriptor fetching working.

This commit is contained in:
4lDO2
2020-03-29 13:49:57 +02:00
parent f3d2d3e2d1
commit 08616920d6
4 changed files with 65 additions and 37 deletions
+2 -2
View File
@@ -406,7 +406,7 @@ impl Xhci {
Some(function(ring_ref))
}
pub fn next_transfer_event_trb(&self, ring_id: RingId, trb: &Trb) -> impl Future<Output = NextEventTrb> + Send + Sync + 'static {
pub fn next_transfer_event_trb(&self, ring_id: RingId, ring: &Ring, trb: &Trb) -> impl Future<Output = NextEventTrb> + 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)),
},
+33 -18
View File
@@ -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<T>(&self, port: usize, slot: u8, kind: usb::DescriptorKind, index: u8, ring: &mut Ring, desc: &mut Dma<T>) -> Result<()> {
async fn get_desc_raw<T>(&self, port: usize, slot: u8, kind: usb::DescriptorKind, index: u8, desc: &mut Dma<T>) -> Result<()> {
println!("A");
let len = mem::size_of::<T>();
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<usb::DeviceDescriptor> {
async fn fetch_dev_desc(&self, port: usize, slot: u8) -> Result<usb::DeviceDescriptor> {
let mut desc = Dma::<usb::DeviceDescriptor>::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<String> {
async fn fetch_string_desc(&self, port: usize, slot: u8, index: u8) -> Result<String> {
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::<BTreeMap<_, _>>(),
};
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)
}
+26 -15
View File
@@ -192,7 +192,6 @@ impl Xhci {
&self,
port_id: usize,
slot: u8,
ring: &mut Ring,
desc: usb::InterfaceDescriptor,
endps: impl IntoIterator<Item = EndpDesc>,
hid_descs: impl IntoIterator<Item = HidDesc>,
@@ -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<DevDesc> {
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
},
+4 -2
View File
@@ -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),
);
}