1#[macro_use]
27mod macros;
28
29use bit_field::BitField;
30use core::convert::TryInto;
31use core::fmt;
32use num_derive::FromPrimitive;
33use num_traits::FromPrimitive;
34
35pub const NUM_OF_ENDPOINT_CONTEXTS: usize = 31;
37
38pub type Input32Byte = Input<8>;
40pub type Input64Byte = Input<16>;
42
43pub type InputControl32Byte = InputControl<8>;
45pub type InputControl64Byte = InputControl<16>;
47
48pub type Device32Byte = Device<8>;
50pub type Device64Byte = Device<16>;
52
53pub type Slot32Byte = Slot<8>;
55pub type Slot64Byte = Slot<16>;
57
58pub type Endpoint32Byte = Endpoint<8>;
60pub type Endpoint64Byte = Endpoint<16>;
62
63#[repr(C)]
67#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
68pub struct Input<const N: usize> {
69 control: InputControl<N>,
70 device: Device<N>,
71}
72impl_constructor!(Input, "Input");
73impl<const N: usize> Input<N> {
74 const fn new() -> Self {
75 Self {
76 control: InputControl::new(),
77 device: Device::new(),
78 }
79 }
80}
81impl<const N: usize> InputHandler for Input<N> {
82 fn control(&self) -> &dyn InputControlHandler {
83 &self.control
84 }
85
86 fn control_mut(&mut self) -> &mut dyn InputControlHandler {
87 &mut self.control
88 }
89
90 fn device(&self) -> &dyn DeviceHandler {
91 &self.device
92 }
93
94 fn device_mut(&mut self) -> &mut dyn DeviceHandler {
95 &mut self.device
96 }
97}
98
99pub trait InputHandler {
101 fn control(&self) -> &dyn InputControlHandler;
103
104 fn control_mut(&mut self) -> &mut dyn InputControlHandler;
106
107 fn device(&self) -> &dyn DeviceHandler;
109
110 fn device_mut(&mut self) -> &mut dyn DeviceHandler;
112}
113
114#[repr(transparent)]
118#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
119pub struct InputControl<const N: usize>([u32; N]);
120impl_constructor!(InputControl, "Input Control");
121impl<const N: usize> InputControl<N> {
122 const fn new() -> Self {
123 Self([0; N])
124 }
125}
126impl<const N: usize> AsRef<[u32]> for InputControl<N> {
127 fn as_ref(&self) -> &[u32] {
128 &self.0
129 }
130}
131impl<const N: usize> AsMut<[u32]> for InputControl<N> {
132 fn as_mut(&mut self) -> &mut [u32] {
133 &mut self.0
134 }
135}
136impl<const N: usize> InputControlHandler for InputControl<N> {}
137impl<const N: usize> fmt::Debug for InputControl<N> {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 f.debug_struct("InputControl")
140 .field("Drop Context flags", &self.0[0])
141 .field("Add Context flags", &self.0[1])
142 .field("configuration_value", &self.configuration_value())
143 .field("interface_number", &self.interface_number())
144 .field("alternate_setting", &self.alternate_setting())
145 .finish()
146 }
147}
148
149pub trait InputControlHandler: AsRef<[u32]> + AsMut<[u32]> {
151 #[must_use]
157 fn drop_context_flag(&self, i: usize) -> bool {
158 self.ensure_drop_context_index_within_range(i);
159
160 self.as_ref()[0].get_bit(i)
161 }
162
163 fn set_drop_context_flag(&mut self, i: usize) {
169 self.ensure_drop_context_index_within_range(i);
170
171 self.as_mut()[0].set_bit(i, true);
172 }
173
174 fn clear_drop_context_flag(&mut self, i: usize) {
180 self.ensure_drop_context_index_within_range(i);
181
182 self.as_mut()[0].set_bit(i, false);
183 }
184
185 #[must_use]
191 fn add_context_flag(&self, i: usize) -> bool {
192 self.ensure_add_context_index_within_range(i);
193
194 self.as_ref()[1].get_bit(i)
195 }
196
197 fn set_add_context_flag(&mut self, i: usize) {
203 self.ensure_add_context_index_within_range(i);
204
205 self.as_mut()[1].set_bit(i, true);
206 }
207
208 fn clear_add_context_flag(&mut self, i: usize) {
214 self.ensure_add_context_index_within_range(i);
215
216 self.as_mut()[1].set_bit(i, false);
217 }
218
219 rw_field_cx!([7](0..=7), configuration_value, "Configuration Value", u8);
220 rw_field_cx!([7](8..=15), interface_number, "Interface Number", u8);
221 rw_field_cx!([7](16..=23), alternate_setting, "Alternate Setting", u8);
222
223 #[doc(hidden)]
224 fn ensure_drop_context_index_within_range(&self, i: usize) {
225 assert!(
226 (2..=31).contains(&i),
227 "The index of Drop Context flag must be within 2..=31."
228 );
229 }
230
231 #[doc(hidden)]
232 fn ensure_add_context_index_within_range(&self, i: usize) {
233 assert!(
234 i <= 31,
235 "The index of Add Context flag must be less than 32."
236 );
237 }
238}
239
240#[repr(C)]
244#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
245pub struct Device<const N: usize> {
246 slot: Slot<N>,
247 endpoints: [Endpoint<N>; NUM_OF_ENDPOINT_CONTEXTS],
248}
249impl_constructor!(Device, "Device");
250impl<const N: usize> Device<N> {
251 const fn new() -> Self {
252 Self {
253 slot: Slot::new(),
254 endpoints: [Endpoint::new(); NUM_OF_ENDPOINT_CONTEXTS],
255 }
256 }
257
258 fn assert_dci(dci: usize) {
259 assert_ne!(
260 dci, 0,
261 "Call `DeviceHandler::slot` to get a handler of Slot Context.`"
262 );
263 assert!(dci <= 31, "DCI must be less than 32.");
264 }
265}
266impl<const N: usize> DeviceHandler for Device<N> {
267 fn slot(&self) -> &dyn SlotHandler {
268 &self.slot
269 }
270
271 fn slot_mut(&mut self) -> &mut dyn SlotHandler {
272 &mut self.slot
273 }
274
275 fn endpoint(&self, dci: usize) -> &dyn EndpointHandler {
276 Self::assert_dci(dci);
277
278 &self.endpoints[dci - 1]
279 }
280
281 fn endpoint_mut(&mut self, dci: usize) -> &mut dyn EndpointHandler {
282 Self::assert_dci(dci);
283
284 &mut self.endpoints[dci - 1]
285 }
286}
287
288pub trait DeviceHandler {
290 fn slot(&self) -> &dyn SlotHandler;
292
293 fn slot_mut(&mut self) -> &mut dyn SlotHandler;
295
296 fn endpoint(&self, dci: usize) -> &dyn EndpointHandler;
303
304 fn endpoint_mut(&mut self, dci: usize) -> &mut dyn EndpointHandler;
311}
312
313#[repr(transparent)]
317#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
318pub struct Slot<const N: usize>([u32; N]);
319impl_constructor!(Slot, "Slot");
320impl<const N: usize> Slot<N> {
321 const fn new() -> Self {
322 Self([0; N])
323 }
324}
325impl<const N: usize> AsRef<[u32]> for Slot<N> {
326 fn as_ref(&self) -> &[u32] {
327 &self.0
328 }
329}
330impl<const N: usize> AsMut<[u32]> for Slot<N> {
331 fn as_mut(&mut self) -> &mut [u32] {
332 &mut self.0
333 }
334}
335impl<const N: usize> SlotHandler for Slot<N> {}
336impl_debug_from_methods_cx! {
337 Slot {
338 route_string,
339 speed,
340 multi_tt,
341 hub,
342 context_entries,
343 max_exit_latency,
344 root_hub_port_number,
345 number_of_ports,
346 parent_hub_slot_id,
347 parent_port_number,
348 tt_think_time,
349 interrupter_target,
350 usb_device_address,
351 slot_state,
352 }
353}
354
355pub trait SlotHandler: AsRef<[u32]> + AsMut<[u32]> {
357 rw_field_cx!([0](0..=19), route_string, "Route String", u32);
358 rw_field_cx!([0](20..=23), speed, "Speed", u8);
359 rw_bit_cx!([0](25), multi_tt, "Multi-TT");
360 rw_bit_cx!([0](26), hub, "Hub");
361 rw_field_cx!([0](27..=31), context_entries, "Context Entries", u8);
362
363 rw_field_cx!([1](0..=15), max_exit_latency, "Max Exit Latency", u16);
364 rw_field_cx!(
365 [1](16..=23),
366 root_hub_port_number,
367 "Root Hub Port Number",
368 u8
369 );
370 rw_field_cx!([1](24..=31), number_of_ports, "Number of Ports", u8);
371
372 rw_field_cx!([2](0..=7), parent_hub_slot_id, "Parent Hub Slot ID", u8);
373 rw_field_cx!([2](8..=15), parent_port_number, "Parent Port Number", u8);
374 rw_field_cx!([2](16..=17), tt_think_time, "TT Think Time", u8);
375 rw_field_cx!([2](22..=31), interrupter_target, "Interrupter Target", u16);
376
377 rw_field_cx!([3](0..=7), usb_device_address, "USB Device Address", u8);
378 #[must_use]
384 fn slot_state(&self) -> SlotState {
385 let v = self.as_ref()[3].get_bits(27..=31);
386 let s = FromPrimitive::from_u32(v);
387 s.expect("Slot State represents Reserved.")
388 }
389
390 fn set_slot_state(&mut self, state: SlotState) {
392 self.as_mut()[3].set_bits(27..=31, state as _);
393 }
394}
395
396#[repr(transparent)]
400#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
401pub struct Endpoint<const N: usize>([u32; N]);
402impl_constructor!(Endpoint, "Endpoint");
403impl<const N: usize> Endpoint<N> {
404 const fn new() -> Self {
405 Self([0; N])
406 }
407}
408impl<const N: usize> AsRef<[u32]> for Endpoint<N> {
409 fn as_ref(&self) -> &[u32] {
410 &self.0
411 }
412}
413impl<const N: usize> AsMut<[u32]> for Endpoint<N> {
414 fn as_mut(&mut self) -> &mut [u32] {
415 &mut self.0
416 }
417}
418impl<const N: usize> EndpointHandler for Endpoint<N> {}
419impl_debug_from_methods_cx! {
420 Endpoint {
421 endpoint_state,
422 mult,
423 max_primary_streams,
424 linear_stream_array,
425 interval,
426 max_endpoint_service_time_interval_payload_high,
427 error_count,
428 endpoint_type,
429 host_initiate_disable,
430 max_burst_size,
431 max_packet_size,
432 dequeue_cycle_state,
433 tr_dequeue_pointer,
434 average_trb_length,
435 max_endpoint_service_time_interval_payload_low,
436 }
437}
438
439pub trait EndpointHandler: AsRef<[u32]> + AsMut<[u32]> {
441 #[must_use]
447 fn endpoint_state(&self) -> EndpointState {
448 let v = self.as_ref()[0].get_bits(0..=2);
449 let s = FromPrimitive::from_u32(v);
450 s.expect("Endpoint State represents Reserved.")
451 }
452
453 fn set_endpoint_state(&mut self, s: EndpointState) {
455 self.as_mut()[0].set_bits(0..=2, s as _);
456 }
457
458 rw_field_cx!([0](8..=9), mult, "Mult", u8);
459 rw_field_cx!([0](10..=14), max_primary_streams, "Max Primary Streams", u8);
460 rw_bit_cx!([0](15), linear_stream_array, "Linear Stream Array");
461 rw_field_cx!([0](16..=23), interval, "Interval", u8);
462 rw_field_cx!(
463 [0](24..=31),
464 max_endpoint_service_time_interval_payload_high,
465 "Max Endpoint Service Time Interval Payload High",
466 u8
467 );
468
469 rw_field_cx!([1](1..=2), error_count, "Error Count", u8);
470 #[must_use]
472 fn endpoint_type(&self) -> EndpointType {
473 let v = self.as_ref()[1].get_bits(3..=5);
474 let t = FromPrimitive::from_u32(v);
475 t.expect("Invalid Endpoint Type.")
476 }
477
478 fn set_endpoint_type(&mut self, t: EndpointType) {
480 self.as_mut()[1].set_bits(3..=5, t as _);
481 }
482
483 rw_bit_cx!([1](7), host_initiate_disable, "Host Initiate Disable");
484 rw_field_cx!([1](8..=15), max_burst_size, "Max Burst Size", u8);
485 rw_field_cx!([1](16..=31), max_packet_size, "Max Packet Size", u16);
486
487 rw_bit_cx!([2](0), dequeue_cycle_state, "Dequeue Cycle State");
488
489 #[must_use]
491 fn tr_dequeue_pointer(&self) -> u64 {
492 let l: u64 = self.as_ref()[2].into();
493 let u: u64 = self.as_ref()[3].into();
494
495 (u << 32) | l
496 }
497
498 fn set_tr_dequeue_pointer(&mut self, a: u64) {
504 assert_eq!(a % 64, 0, "TR Dequeue Pointer must be 64-byte aligned.");
505
506 let l: u32 = a.get_bits(0..32).try_into().unwrap();
507 let u: u32 = a.get_bits(32..64).try_into().unwrap();
508
509 self.as_mut()[2] = l;
510 self.as_mut()[3] = u;
511 }
512
513 rw_field_cx!([4](0..=15), average_trb_length, "Average TRB Length", u16);
514 rw_field_cx!(
515 [4](16..=31),
516 max_endpoint_service_time_interval_payload_low,
517 "Max Endpoint Service Time Interval Payload Low",
518 u16
519 );
520}
521
522#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, FromPrimitive)]
524pub enum SlotState {
525 DisabledEnabled = 0,
527 Default = 1,
529 Addressed = 2,
531 Configured = 3,
533}
534
535#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, FromPrimitive)]
539pub enum EndpointState {
540 Disabled = 0,
542 Running = 1,
544 Halted = 2,
546 Stopped = 3,
549 Error = 4,
551}
552
553#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, FromPrimitive)]
555pub enum EndpointType {
556 NotValid = 0,
558 IsochOut = 1,
560 BulkOut = 2,
562 InterruptOut = 3,
564 Control = 4,
566 IsochIn = 5,
568 BulkIn = 6,
570 InterruptIn = 7,
572}