Get descriptor fetching working.
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||
},
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user