use super::Link;
use bit_field::BitField;
use core::convert::TryInto;
allowed! {
enum {
Link,
EnableSlot,
DisableSlot,
AddressDevice,
ConfigureEndpoint,
EvaluateContext,
ResetEndpoint,
StopEndpoint,
SetTrDequeuePointer,
ResetDevice,
ForceEvent,
NegotiateBandwidth,
SetLatencyToleranceValue,
GetPortBandwidth,
ForceHeader,
Noop,
GetExtendedProperty,
SetExtendedProperty
}
}
add_trb_with_default!(Noop, "No Op Command TRB", Type::NoopCommand);
impl_debug_for_trb!(Noop {});
add_trb_with_default!(EnableSlot, "Enable Slot Command TRB", Type::EnableSlot);
impl EnableSlot {
pub fn set_slot_type(&mut self, t: u8) -> &mut Self {
self.0[3].set_bits(16..=20, t.into());
self
}
#[must_use]
pub fn slot_type(&self) -> u8 {
self.0[3].get_bits(16..=20).try_into().unwrap()
}
}
impl_debug_for_trb!(EnableSlot { slot_type });
add_trb_with_default!(DisableSlot, "Disable Slot Command TRB", Type::DisableSlot);
impl DisableSlot {
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(DisableSlot { slot_id });
add_trb_with_default!(
AddressDevice,
"Address Device Command TRB",
Type::AddressDevice
);
impl AddressDevice {
pub fn set_input_context_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The Input Context Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn input_context_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_block_set_address_request(&mut self, r: bool) -> &mut Self {
self.0[3].set_bit(9, r);
self
}
#[must_use]
pub fn block_set_address_request(&self) -> bool {
self.0[3].get_bit(9)
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(AddressDevice {
input_context_pointer,
block_set_address_request,
slot_id
});
add_trb_with_default!(
ConfigureEndpoint,
"Configure Endpoint Command TRB",
Type::ConfigureEndpoint
);
impl ConfigureEndpoint {
pub fn set_input_context_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The Input Context Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn input_context_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_deconfigure(&mut self, d: bool) -> &mut Self {
self.0[3].set_bit(9, d);
self
}
#[must_use]
pub fn deconfigure(&self) -> bool {
self.0[3].get_bit(9)
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(ConfigureEndpoint {
input_context_pointer,
deconfigure,
slot_id
});
add_trb_with_default!(
EvaluateContext,
"Evaluate Context Command TRB",
Type::EvaluateContext
);
impl EvaluateContext {
pub fn set_input_context_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The Input Context Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn input_context_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(EvaluateContext {
input_context_pointer,
slot_id
});
add_trb_with_default!(
ResetEndpoint,
"Reset Endpoint Command TRB",
Type::ResetEndpoint
);
impl ResetEndpoint {
pub fn set_transfer_state_preserve(&mut self, tsp: bool) -> &mut Self {
self.0[3].set_bit(9, tsp);
self
}
#[must_use]
pub fn transfer_state_preserve(&self) -> bool {
self.0[3].get_bit(9)
}
pub fn set_endpoint_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(16..=20, i.into());
self
}
#[must_use]
pub fn endpoint_id(&self) -> u8 {
self.0[3].get_bits(16..=20).try_into().unwrap()
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(ResetEndpoint {
transfer_state_preserve,
endpoint_id,
slot_id
});
add_trb_with_default!(
StopEndpoint,
"Stop Endpoint Command TRB",
Type::StopEndpoint
);
impl StopEndpoint {
pub fn set_endpoint_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(16..=20, i.into());
self
}
#[must_use]
pub fn endpoint_id(&self) -> u8 {
self.0[3].get_bits(16..=20).try_into().unwrap()
}
pub fn set_suspend(&mut self, s: bool) -> &mut Self {
self.0[3].set_bit(23, s);
self
}
#[must_use]
pub fn suspend(&self) -> bool {
self.0[3].get_bit(23)
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(StopEndpoint {
endpoint_id,
suspend,
slot_id
});
add_trb_with_default!(
SetTrDequeuePointer,
"Set TR Dequeue Pointer Command TRB",
Type::SetTrDequeuePointer
);
impl SetTrDequeuePointer {
pub fn set_dequeue_cycle_state(&mut self, s: bool) -> &mut Self {
self.0[0].set_bit(0, s);
self
}
#[must_use]
pub fn dequeue_cycle_state(&self) -> bool {
self.0[0].get_bit(0)
}
pub fn set_stream_context_type(&mut self, t: u8) -> &mut Self {
self.0[0].set_bits(1..=3, t.into());
self
}
#[must_use]
pub fn stream_context_type(&self) -> u8 {
self.0[0].get_bits(1..=3).try_into().unwrap()
}
pub fn set_new_tr_dequeue_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The New TR Dequeue Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0].set_bits(4..32, l.get_bits(4..32).try_into().unwrap());
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn new_tr_dequeue_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
((u << 32) | l) & 0xffff_fff0
}
pub fn set_stream_id(&mut self, i: u16) -> &mut Self {
self.0[2].set_bits(16..=31, i.into());
self
}
#[must_use]
pub fn stream_id(&self) -> u16 {
self.0[2].get_bits(16..=31).try_into().unwrap()
}
pub fn set_endpoint_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(16..=20, i.into());
self
}
#[must_use]
pub fn endpoint_id(&self) -> u8 {
self.0[3].get_bits(16..=20).try_into().unwrap()
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(SetTrDequeuePointer {
dequeue_cycle_state,
stream_context_type,
new_tr_dequeue_pointer,
stream_id,
endpoint_id,
slot_id
});
add_trb_with_default!(ResetDevice, "Reset Device Command TRB", Type::ResetDevice);
impl ResetDevice {
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(ResetDevice { slot_id });
add_trb_with_default!(ForceEvent, "Force Event Command TRB", Type::ForceEvent);
impl ForceEvent {
pub fn set_event_trb_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(p % 16, 0, "The Event TRB Pointer must be 16-byte aligned.");
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn event_trb_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_vf_interrupter_target(&mut self, t: u16) -> &mut Self {
self.0[2].set_bits(22..=31, t.into());
self
}
#[must_use]
pub fn vf_interrupter_target(&self) -> u16 {
self.0[2].get_bits(22..=31).try_into().unwrap()
}
pub fn set_vf_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(16..=23, i.into());
self
}
#[must_use]
pub fn vf_id(&self) -> u8 {
self.0[3].get_bits(16..=23).try_into().unwrap()
}
}
impl_debug_for_trb!(ForceEvent {
event_trb_pointer,
vf_interrupter_target,
vf_id
});
add_trb_with_default!(
NegotiateBandwidth,
"Negotiate Bandwidth Command TRB",
Type::NegotiateBandwidth
);
impl NegotiateBandwidth {
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(NegotiateBandwidth { slot_id });
add_trb_with_default!(
SetLatencyToleranceValue,
"Set Latency Tolerance Value Command TRB",
Type::SetLatencyToleranceValue
);
impl SetLatencyToleranceValue {
pub fn set_best_effort_latency_tolerance_value(&mut self, v: u16) -> &mut Self {
self.0[3].set_bits(16..=27, v.into());
self
}
#[must_use]
pub fn best_effort_latency_tolerance_value(&self) -> u16 {
self.0[3].get_bits(16..=27).try_into().unwrap()
}
}
impl_debug_for_trb!(SetLatencyToleranceValue {
best_effort_latency_tolerance_value
});
add_trb_with_default!(
GetPortBandwidth,
"Get Port Bandwidth Command TRB",
Type::GetPortBandwidth
);
impl GetPortBandwidth {
pub fn set_port_bandwidth_context_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The Port Bandwidth Context Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn port_bandwidth_context_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_dev_speed(&mut self, s: u8) -> &mut Self {
self.0[3].set_bits(16..=19, s.into());
self
}
#[must_use]
pub fn dev_speed(&self) -> u8 {
self.0[3].get_bits(16..=19).try_into().unwrap()
}
pub fn set_hub_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn hub_slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(GetPortBandwidth {
port_bandwidth_context_pointer,
dev_speed,
hub_slot_id
});
add_trb_with_default!(ForceHeader, "Force Header Command TRB", Type::ForceHeader);
impl ForceHeader {
pub fn set_packet_type(&mut self, t: u8) -> &mut Self {
self.0[0].set_bits(0..=4, t.into());
self
}
#[must_use]
pub fn packet_type(&self) -> u8 {
self.0[0].get_bits(0..=4).try_into().unwrap()
}
pub fn set_header_info(&mut self, info: [u32; 3]) -> &mut Self {
assert!(
info[0].trailing_zeros() >= 5,
"The lowest 5 bits of the Header Info Low must be 0."
);
self.0[0].set_bits(5..=31, info[0].get_bits(5..=31));
self.0[1] = info[1];
self.0[2] = info[2];
self
}
#[must_use]
pub fn header_info(&self) -> [u32; 3] {
[self.0[0] & 0xffff_ffe0, self.0[1], self.0[2]]
}
pub fn set_root_hub_port_number(&mut self, n: u8) -> &mut Self {
self.0[3].set_bits(24..=31, n.into());
self
}
#[must_use]
pub fn root_hub_port_number(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(ForceHeader {
packet_type,
header_info,
root_hub_port_number
});
add_trb_with_default!(
GetExtendedProperty,
"Get Extended Property Command TRB",
Type::GetExtendedProperty
);
impl GetExtendedProperty {
pub fn set_extended_property_context_pointer(&mut self, p: u64) -> &mut Self {
assert_eq!(
p % 16,
0,
"The Extended Property Context Pointer must be 16-byte aligned."
);
let l = p.get_bits(0..32);
let u = p.get_bits(32..64);
self.0[0] = l.try_into().unwrap();
self.0[1] = u.try_into().unwrap();
self
}
#[must_use]
pub fn extended_property_context_pointer(&self) -> u64 {
let l: u64 = self.0[0].into();
let u: u64 = self.0[1].into();
(u << 32) | l
}
pub fn set_extended_capability_identifier(&mut self, eci: u16) -> &mut Self {
self.0[2].set_bits(0..=15, eci.into());
self
}
#[must_use]
pub fn extended_capability_identifier(&self) -> u16 {
self.0[2].get_bits(0..=15).try_into().unwrap()
}
pub fn set_command_sub_type(&mut self, t: u8) -> &mut Self {
self.0[3].set_bits(16..=18, t.into());
self
}
#[must_use]
pub fn command_sub_type(&self) -> u8 {
self.0[3].get_bits(16..=18).try_into().unwrap()
}
pub fn set_endpoint_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(19..=23, i.into());
self
}
#[must_use]
pub fn endpoint_id(&self) -> u8 {
self.0[3].get_bits(19..=23).try_into().unwrap()
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(GetExtendedProperty {
extended_property_context_pointer,
extended_capability_identifier,
command_sub_type,
endpoint_id,
slot_id
});
add_trb_with_default!(
SetExtendedProperty,
"Set Extended Property Command TRB",
Type::SetExtendedProperty
);
impl SetExtendedProperty {
pub fn set_extended_capability_identifier(&mut self, eci: u16) -> &mut Self {
self.0[2].set_bits(0..=15, eci.into());
self
}
#[must_use]
pub fn extended_capability_identifier(&self) -> u16 {
self.0[2].get_bits(0..=15).try_into().unwrap()
}
pub fn set_capability_parameter(&mut self, p: u8) -> &mut Self {
self.0[2].set_bits(15..=23, p.into());
self
}
#[must_use]
pub fn capability_parameter(&self) -> u8 {
self.0[2].get_bits(15..=23).try_into().unwrap()
}
pub fn set_command_sub_type(&mut self, t: u8) -> &mut Self {
self.0[3].set_bits(16..=18, t.into());
self
}
#[must_use]
pub fn command_sub_type(&self) -> u8 {
self.0[3].get_bits(16..=18).try_into().unwrap()
}
pub fn set_endpoint_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(19..=23, i.into());
self
}
#[must_use]
pub fn endpoint_id(&self) -> u8 {
self.0[3].get_bits(19..=23).try_into().unwrap()
}
pub fn set_slot_id(&mut self, i: u8) -> &mut Self {
self.0[3].set_bits(24..=31, i.into());
self
}
#[must_use]
pub fn slot_id(&self) -> u8 {
self.0[3].get_bits(24..=31).try_into().unwrap()
}
}
impl_debug_for_trb!(SetExtendedProperty {
extended_capability_identifier,
capability_parameter,
command_sub_type,
endpoint_id,
slot_id
});