• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use bit_field::Error as BitFieldError;
6 use bit_field::*;
7 use data_model::DataInit;
8 use std::fmt::{self, Display};
9 use sys_util::GuestAddress;
10 
11 use std;
12 
13 #[derive(Debug)]
14 pub enum Error {
15     UnknownTrbType(BitFieldError),
16     CannotCastTrb,
17 }
18 
19 type Result<T> = std::result::Result<T, Error>;
20 
21 impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result22     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23         use self::Error::*;
24 
25         match self {
26             UnknownTrbType(e) => write!(f, "we got an unknown trb type value: {}", e),
27             CannotCastTrb => write!(f, "cannot cast trb from raw memory"),
28         }
29     }
30 }
31 
32 // Fixed size of all TRB types.
33 const TRB_SIZE: usize = 16;
34 
35 // Size of segment table.
36 const SEGMENT_TABLE_SIZE: usize = 16;
37 
38 /// All kinds of trb.
39 #[bitfield]
40 #[bits = 6]
41 #[derive(PartialEq, Debug, Clone, Copy)]
42 pub enum TrbType {
43     Reserved = 0,
44     Normal = 1,
45     SetupStage = 2,
46     DataStage = 3,
47     StatusStage = 4,
48     Isoch = 5,
49     Link = 6,
50     EventData = 7,
51     Noop = 8,
52     EnableSlotCommand = 9,
53     DisableSlotCommand = 10,
54     AddressDeviceCommand = 11,
55     ConfigureEndpointCommand = 12,
56     EvaluateContextCommand = 13,
57     ResetEndpointCommand = 14,
58     StopEndpointCommand = 15,
59     SetTRDequeuePointerCommand = 16,
60     ResetDeviceCommand = 17,
61     NoopCommand = 23,
62     TransferEvent = 32,
63     CommandCompletionEvent = 33,
64     PortStatusChangeEvent = 34,
65 }
66 
67 /// Completion code of trb types.
68 #[bitfield]
69 #[bits = 8]
70 #[derive(PartialEq, Debug)]
71 pub enum TrbCompletionCode {
72     Success = 1,
73     TransactionError = 4,
74     TrbError = 5,
75     NoSlotsAvailableError = 9,
76     SlotNotEnabledError = 11,
77     ShortPacket = 13,
78     ContextStateError = 19,
79 }
80 
81 /// State of device slot.
82 #[bitfield]
83 #[bits = 5]
84 #[derive(PartialEq, Debug)]
85 pub enum DeviceSlotState {
86     // The same value (0) is used for both the enabled and disabled states. See
87     // xhci spec table 60.
88     DisabledOrEnabled = 0,
89     Default = 1,
90     Addressed = 2,
91     Configured = 3,
92 }
93 
94 /// State of endpoint.
95 #[bitfield]
96 #[bits = 3]
97 #[derive(PartialEq, Debug)]
98 pub enum EndpointState {
99     Disabled = 0,
100     Running = 1,
101 }
102 
103 #[bitfield]
104 #[bits = 60]
105 #[derive(PartialEq, Debug)]
106 pub struct DequeuePtr(u64);
107 
108 impl DequeuePtr {
new(addr: GuestAddress) -> Self109     pub fn new(addr: GuestAddress) -> Self {
110         DequeuePtr(addr.0 >> 4)
111     }
112 
113     // Get the guest physical address.
get_gpa(&self) -> GuestAddress114     pub fn get_gpa(&self) -> GuestAddress {
115         GuestAddress(self.0 << 4)
116     }
117 }
118 
119 // Generic TRB struct containing only fields common to all types.
120 #[bitfield]
121 #[derive(Clone, Copy, PartialEq)]
122 pub struct Trb {
123     parameter: B64,
124     status: B32,
125     cycle: bool,
126     flags: B9,
127     trb_type: TrbType,
128     control: B16,
129 }
130 
131 impl Trb {
fmt_helper(&self, f: &mut fmt::Formatter) -> Result<fmt::Result>132     fn fmt_helper(&self, f: &mut fmt::Formatter) -> Result<fmt::Result> {
133         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
134             TrbType::Reserved => Ok(write!(f, "reserved trb type")),
135             TrbType::Normal => {
136                 let t = self.cast::<NormalTrb>()?;
137                 Ok(write!(f, "trb: {:?}", t))
138             }
139             TrbType::SetupStage => {
140                 let t = self.cast::<SetupStageTrb>()?;
141                 Ok(write!(f, "trb: {:?}", t))
142             }
143             TrbType::DataStage => {
144                 let t = self.cast::<DataStageTrb>()?;
145                 Ok(write!(f, "trb: {:?}", t))
146             }
147             TrbType::StatusStage => {
148                 let t = self.cast::<StatusStageTrb>()?;
149                 Ok(write!(f, "trb: {:?}", t))
150             }
151             TrbType::Isoch => {
152                 let t = self.cast::<IsochTrb>()?;
153                 Ok(write!(f, "trb: {:?}", t))
154             }
155             TrbType::Link => {
156                 let t = self.cast::<LinkTrb>()?;
157                 Ok(write!(f, "trb: {:?}", t))
158             }
159             TrbType::EventData => {
160                 let t = self.cast::<EventDataTrb>()?;
161                 Ok(write!(f, "trb: {:?}", t))
162             }
163             TrbType::Noop => {
164                 let t = self.cast::<NoopTrb>()?;
165                 Ok(write!(f, "trb: {:?}", t))
166             }
167             TrbType::EnableSlotCommand => Ok(write!(f, "trb: enable slot command {:?}", self)),
168             TrbType::DisableSlotCommand => {
169                 let t = self.cast::<DisableSlotCommandTrb>()?;
170                 Ok(write!(f, "trb: {:?}", t))
171             }
172             TrbType::AddressDeviceCommand => {
173                 let t = self.cast::<AddressDeviceCommandTrb>()?;
174                 Ok(write!(f, "trb: {:?}", t))
175             }
176             TrbType::ConfigureEndpointCommand => {
177                 let t = self.cast::<ConfigureEndpointCommandTrb>()?;
178                 Ok(write!(f, "trb: {:?}", t))
179             }
180             TrbType::EvaluateContextCommand => {
181                 let t = self.cast::<EvaluateContextCommandTrb>()?;
182                 Ok(write!(f, "trb: {:?}", t))
183             }
184             TrbType::ResetEndpointCommand => {
185                 let t = self.cast::<ResetEndpointCommandTrb>()?;
186                 Ok(write!(f, "trb: {:?}", t))
187             }
188             TrbType::StopEndpointCommand => {
189                 let t = self.cast::<StopEndpointCommandTrb>()?;
190                 Ok(write!(f, "trb: {:?}", t))
191             }
192             TrbType::SetTRDequeuePointerCommand => {
193                 let t = self.cast::<SetTRDequeuePointerCommandTrb>()?;
194                 Ok(write!(f, "trb: {:?}", t))
195             }
196             TrbType::ResetDeviceCommand => {
197                 let t = self.cast::<ResetDeviceCommandTrb>()?;
198                 Ok(write!(f, "trb: {:?}", t))
199             }
200             TrbType::NoopCommand => Ok(write!(f, "trb: noop command {:?}", self)),
201             TrbType::TransferEvent => {
202                 let t = self.cast::<TransferEventTrb>()?;
203                 Ok(write!(f, "trb: {:?}", t))
204             }
205             TrbType::CommandCompletionEvent => {
206                 let t = self.cast::<CommandCompletionEventTrb>()?;
207                 Ok(write!(f, "trb: {:?}", t))
208             }
209             TrbType::PortStatusChangeEvent => {
210                 let t = self.cast::<PortStatusChangeEventTrb>()?;
211                 Ok(write!(f, "trb: {:?}", t))
212             }
213         }
214     }
215 }
216 
217 impl Display for Trb {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result218     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
219         match self.fmt_helper(f) {
220             Ok(f) => f,
221             Err(e) => write!(f, "fail to format trb {}", e),
222         }
223     }
224 }
225 
226 impl Trb {
227     /// Get chain bit.
get_chain_bit(&self) -> Result<bool>228     pub fn get_chain_bit(&self) -> Result<bool> {
229         Ok(match self.get_trb_type() {
230             Ok(TrbType::Normal) => self.cast::<NormalTrb>()?.get_chain(),
231             Ok(TrbType::DataStage) => self.cast::<DataStageTrb>()?.get_chain(),
232             Ok(TrbType::StatusStage) => self.cast::<StatusStageTrb>()?.get_chain(),
233             Ok(TrbType::Isoch) => self.cast::<IsochTrb>()?.get_chain(),
234             Ok(TrbType::Noop) => self.cast::<NoopTrb>()?.get_chain(),
235             Ok(TrbType::Link) => self.cast::<LinkTrb>()?.get_chain(),
236             Ok(TrbType::EventData) => self.cast::<EventDataTrb>()?.get_chain(),
237             _ => false,
238         })
239     }
240 
241     /// Get interrupt target.
interrupter_target(&self) -> u8242     pub fn interrupter_target(&self) -> u8 {
243         const STATUS_INTERRUPTER_TARGET_OFFSET: u8 = 22;
244         (self.get_status() >> STATUS_INTERRUPTER_TARGET_OFFSET) as u8
245     }
246 
247     /// Only some of trb types could appear in transfer ring.
can_be_in_transfer_ring(&self) -> Result<bool>248     pub fn can_be_in_transfer_ring(&self) -> Result<bool> {
249         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
250             TrbType::Normal
251             | TrbType::SetupStage
252             | TrbType::DataStage
253             | TrbType::StatusStage
254             | TrbType::Isoch
255             | TrbType::Link
256             | TrbType::EventData
257             | TrbType::Noop => Ok(true),
258             _ => Ok(false),
259         }
260     }
261 
262     /// Length of this transfer.
transfer_length(&self) -> Result<u32>263     pub fn transfer_length(&self) -> Result<u32> {
264         const STATUS_TRANSFER_LENGTH_MASK: u32 = 0x1ffff;
265         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
266             TrbType::Normal | TrbType::SetupStage | TrbType::DataStage | TrbType::Isoch => {
267                 Ok(self.get_status() & STATUS_TRANSFER_LENGTH_MASK)
268             }
269             _ => Ok(0),
270         }
271     }
272 
273     /// Returns true if interrupt is required on completion.
interrupt_on_completion(&self) -> bool274     pub fn interrupt_on_completion(&self) -> bool {
275         const FLAGS_INTERRUPT_ON_COMPLETION_MASK: u16 = 0x10;
276         (self.get_flags() & FLAGS_INTERRUPT_ON_COMPLETION_MASK) > 0
277     }
278 
279     /// Returns true if interrupt is required on transfer of short packet.
interrupt_on_short_packet(&self) -> bool280     pub fn interrupt_on_short_packet(&self) -> bool {
281         const FLAGS_INTERRUPT_ON_SHORT_PACKET: u16 = 0x2;
282         (self.get_flags() & FLAGS_INTERRUPT_ON_SHORT_PACKET) > 0
283     }
284 
285     /// Returns true if this trb is immediate data.
immediate_data(&self) -> Result<bool>286     pub fn immediate_data(&self) -> Result<bool> {
287         const FLAGS_IMMEDIATE_DATA_MASK: u16 = 0x20;
288         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
289             TrbType::Normal | TrbType::SetupStage | TrbType::DataStage | TrbType::Isoch => {
290                 Ok((self.get_flags() & FLAGS_IMMEDIATE_DATA_MASK) != 0)
291             }
292             _ => Ok(false),
293         }
294     }
295 }
296 
297 #[bitfield]
298 #[derive(Clone, Copy)]
299 pub struct NormalTrb {
300     data_buffer: B64,
301     trb_transfer_length: B17,
302     td_size: B5,
303     interrupter_target: B10,
304     cycle: bool,
305     evaluate_next_trb: B1,
306     interrupt_on_short_packet: B1,
307     no_snoop: B1,
308     chain: bool,
309     interrupt_on_completion: B1,
310     immediate_data: B1,
311     reserved: B2,
312     block_event_interrupt: B1,
313     trb_type: TrbType,
314     reserved1: B16,
315 }
316 
317 #[bitfield]
318 #[derive(Clone, Copy)]
319 pub struct SetupStageTrb {
320     request_type: B8,
321     request: B8,
322     value: B16,
323     index: B16,
324     length: B16,
325     trb_transfer_length: B17,
326     reserved0: B5,
327     interrupter_target: B10,
328     cycle: bool,
329     reserved1: B4,
330     interrupt_on_completion: B1,
331     immediate_data: B1,
332     reserved2: B3,
333     trb_type: TrbType,
334     transfer_type: B2,
335     reserved3: B14,
336 }
337 
338 #[bitfield]
339 #[derive(Clone, Copy)]
340 pub struct DataStageTrb {
341     data_buffer_pointer: B64,
342     trb_transfer_length: B17,
343     td_size: B5,
344     interrupter_target: B10,
345     cycle: bool,
346     evaluate_next_trb: B1,
347     interrupt_on_short_packet: B1,
348     no_snoop: B1,
349     chain: bool,
350     interrupt_on_completion: B1,
351     immediate_data: B1,
352     reserved0: B3,
353     trb_type: TrbType,
354     direction: B1,
355     reserved1: B15,
356 }
357 
358 #[bitfield]
359 #[derive(Clone, Copy)]
360 pub struct StatusStageTrb {
361     reserved0: B64,
362     reserved1: B22,
363     interrupter_target: B10,
364     cycle: bool,
365     evaluate_next_trb: B1,
366     reserved2: B2,
367     chain: bool,
368     interrupt_on_completion: B1,
369     reserved3: B4,
370     trb_type: TrbType,
371     direction: B1,
372     reserved4: B15,
373 }
374 
375 #[bitfield]
376 #[derive(Clone, Copy)]
377 pub struct IsochTrb {
378     data_buffer_pointer: B64,
379     trb_transfer_length: B17,
380     td_size: B5,
381     interrupter_target: B10,
382     cycle: bool,
383     evaulate_nex_trb: B1,
384     interrupt_on_short_packet: B1,
385     no_snoop: B1,
386     chain: bool,
387     interrupt_on_completion: B1,
388     immediate_data: B1,
389     transfer_burst_count: B2,
390     block_event_interrupt: B1,
391     trb_type: TrbType,
392     tlbpc: B4,
393     frame_id: B11,
394     sia: B1,
395 }
396 
397 #[bitfield]
398 #[derive(Clone, Copy)]
399 pub struct LinkTrb {
400     ring_segment_pointer: B64,
401     reserved0: B22,
402     interrupter_target: B10,
403     cycle: bool,
404     toggle_cycle: bool,
405     reserved1: B2,
406     chain: bool,
407     interrupt_on_completion: bool,
408     reserved2: B4,
409     trb_type: TrbType,
410     reserved3: B16,
411 }
412 
413 #[bitfield]
414 #[derive(Clone, Copy)]
415 pub struct EventDataTrb {
416     event_data: B64,
417     reserved0: B22,
418     interrupter_target: B10,
419     cycle: bool,
420     evaluate_next_trb: B1,
421     reserved1: B2,
422     chain: bool,
423     interrupt_on_completion: B1,
424     reserved2: B3,
425     block_event_interrupt: B1,
426     trb_type: TrbType,
427     reserved3: B16,
428 }
429 
430 #[bitfield]
431 #[derive(Clone, Copy)]
432 pub struct NoopTrb {
433     reserved0: B64,
434     reserved1: B22,
435     interrupter_target: B10,
436     cycle: bool,
437     evaluate_next_trb: B1,
438     reserved2: B2,
439     chain: bool,
440     interrupt_on_completion: B1,
441     reserved3: B4,
442     trb_type: TrbType,
443     reserved4: B16,
444 }
445 
446 #[bitfield]
447 #[derive(Clone, Copy)]
448 pub struct DisableSlotCommandTrb {
449     reserved0: B32,
450     reserved1: B32,
451     reserved2: B32,
452     cycle: bool,
453     reserved3: B9,
454     trb_type: TrbType,
455     reserved4: B8,
456     slot_id: B8,
457 }
458 
459 #[bitfield]
460 #[derive(Clone, Copy)]
461 pub struct AddressDeviceCommandTrb {
462     input_context_pointer: B64,
463     reserved: B32,
464     cycle: bool,
465     reserved2: B8,
466     block_set_address_request: bool,
467     trb_type: TrbType,
468     reserved3: B8,
469     slot_id: B8,
470 }
471 
472 #[bitfield]
473 #[derive(Clone, Copy)]
474 pub struct ConfigureEndpointCommandTrb {
475     input_context_pointer: B64,
476     reserved0: B32,
477     cycle: bool,
478     reserved1: B8,
479     deconfigure: bool,
480     trb_type: TrbType,
481     reserved2: B8,
482     slot_id: B8,
483 }
484 
485 #[bitfield]
486 #[derive(Clone, Copy)]
487 pub struct EvaluateContextCommandTrb {
488     input_context_pointer: B64,
489     reserved0: B32,
490     cycle: bool,
491     reserved1: B9,
492     trb_type: TrbType,
493     reserved2: B8,
494     slot_id: B8,
495 }
496 
497 #[bitfield]
498 #[derive(Clone, Copy)]
499 pub struct ResetEndpointCommandTrb {
500     reserved0: B32,
501     reserved1: B32,
502     reserved2: B32,
503     cycle: bool,
504     reserved3: B8,
505     transfer_state_preserve: B1,
506     trb_type: TrbType,
507     endpoint_id: B5,
508     reserved4: B3,
509     slot_id: B8,
510 }
511 
512 #[bitfield]
513 #[derive(Clone, Copy)]
514 pub struct StopEndpointCommandTrb {
515     reserved0: B32,
516     reserved1: B32,
517     reserved2: B32,
518     cycle: bool,
519     reserved3: B9,
520     trb_type: TrbType,
521     endpoint_id: B5,
522     reserved4: B2,
523     suspend: B1,
524     slot_id: B8,
525 }
526 
527 #[bitfield]
528 #[derive(Clone, Copy)]
529 pub struct SetTRDequeuePointerCommandTrb {
530     dequeue_cycle_state: bool,
531     stream_context_type: B3,
532     dequeue_ptr: DequeuePtr,
533     reserved0: B16,
534     stream_id: B16,
535     cycle: bool,
536     reserved1: B9,
537     trb_type: TrbType,
538     endpoint_id: B5,
539     reserved3: B2,
540     suspend: B1,
541     slot_id: B8,
542 }
543 
544 #[bitfield]
545 #[derive(Clone, Copy)]
546 pub struct ResetDeviceCommandTrb {
547     reserved0: B32,
548     reserved1: B32,
549     reserved2: B32,
550     cycle: bool,
551     reserved3: B9,
552     trb_type: TrbType,
553     reserved4: B8,
554     slot_id: B8,
555 }
556 
557 #[bitfield]
558 #[derive(Clone, Copy)]
559 pub struct TransferEventTrb {
560     trb_pointer: B64,
561     trb_transfer_length: B24,
562     completion_code: TrbCompletionCode,
563     cycle: bool,
564     reserved0: B1,
565     event_data: B1,
566     reserved1: B7,
567     trb_type: TrbType,
568     endpoint_id: B5,
569     reserved2: B3,
570     slot_id: B8,
571 }
572 
573 #[bitfield]
574 #[derive(Clone, Copy)]
575 pub struct CommandCompletionEventTrb {
576     trb_pointer: B64,
577     command_completion_parameter: B24,
578     completion_code: TrbCompletionCode,
579     cycle: bool,
580     reserved: B9,
581     trb_type: TrbType,
582     vf_id: B8,
583     slot_id: B8,
584 }
585 
586 #[bitfield]
587 #[derive(Clone, Copy)]
588 pub struct PortStatusChangeEventTrb {
589     reserved0: B24,
590     port_id: B8,
591     reserved1: B32,
592     reserved2: B24,
593     completion_code: TrbCompletionCode,
594     cycle: bool,
595     reserved3: B9,
596     trb_type: TrbType,
597     reserved4: B16,
598 }
599 
600 /// Associate real type of trb.
601 pub trait TypedTrb {
602     const TY: TrbType;
603 }
604 
605 impl TypedTrb for Trb {
606     const TY: TrbType = TrbType::Reserved;
607 }
608 
609 impl TypedTrb for NormalTrb {
610     const TY: TrbType = TrbType::Normal;
611 }
612 
613 impl TypedTrb for SetupStageTrb {
614     const TY: TrbType = TrbType::SetupStage;
615 }
616 
617 impl TypedTrb for DataStageTrb {
618     const TY: TrbType = TrbType::DataStage;
619 }
620 
621 impl TypedTrb for StatusStageTrb {
622     const TY: TrbType = TrbType::StatusStage;
623 }
624 
625 impl TypedTrb for IsochTrb {
626     const TY: TrbType = TrbType::Isoch;
627 }
628 
629 impl TypedTrb for LinkTrb {
630     const TY: TrbType = TrbType::Link;
631 }
632 
633 impl TypedTrb for EventDataTrb {
634     const TY: TrbType = TrbType::EventData;
635 }
636 
637 impl TypedTrb for NoopTrb {
638     const TY: TrbType = TrbType::Noop;
639 }
640 
641 impl TypedTrb for DisableSlotCommandTrb {
642     const TY: TrbType = TrbType::DisableSlotCommand;
643 }
644 
645 impl TypedTrb for AddressDeviceCommandTrb {
646     const TY: TrbType = TrbType::AddressDeviceCommand;
647 }
648 
649 impl TypedTrb for ConfigureEndpointCommandTrb {
650     const TY: TrbType = TrbType::ConfigureEndpointCommand;
651 }
652 
653 impl TypedTrb for EvaluateContextCommandTrb {
654     const TY: TrbType = TrbType::EvaluateContextCommand;
655 }
656 
657 impl TypedTrb for ResetEndpointCommandTrb {
658     const TY: TrbType = TrbType::ResetEndpointCommand;
659 }
660 
661 impl TypedTrb for StopEndpointCommandTrb {
662     const TY: TrbType = TrbType::StopEndpointCommand;
663 }
664 
665 impl TypedTrb for SetTRDequeuePointerCommandTrb {
666     const TY: TrbType = TrbType::SetTRDequeuePointerCommand;
667 }
668 
669 impl TypedTrb for ResetDeviceCommandTrb {
670     const TY: TrbType = TrbType::ResetDeviceCommand;
671 }
672 
673 impl TypedTrb for TransferEventTrb {
674     const TY: TrbType = TrbType::TransferEvent;
675 }
676 
677 impl TypedTrb for CommandCompletionEventTrb {
678     const TY: TrbType = TrbType::CommandCompletionEvent;
679 }
680 
681 impl TypedTrb for PortStatusChangeEventTrb {
682     const TY: TrbType = TrbType::PortStatusChangeEvent;
683 }
684 
685 /// All trb structs have the same size. One trb could be safely casted to another, though the
686 /// values might be invalid.
687 pub unsafe trait TrbCast: DataInit + TypedTrb {
cast<T: TrbCast>(&self) -> Result<&T>688     fn cast<T: TrbCast>(&self) -> Result<&T> {
689         T::from_slice(self.as_slice()).ok_or(Error::CannotCastTrb)
690     }
691 
cast_mut<T: TrbCast>(&mut self) -> Result<&mut T>692     fn cast_mut<T: TrbCast>(&mut self) -> Result<&mut T> {
693         T::from_mut_slice(self.as_mut_slice()).ok_or(Error::CannotCastTrb)
694     }
695 
checked_cast<T: TrbCast>(&self) -> Result<&T>696     fn checked_cast<T: TrbCast>(&self) -> Result<&T> {
697         if Trb::from_slice(self.as_slice())
698             .ok_or(Error::CannotCastTrb)?
699             .get_trb_type()
700             .map_err(Error::UnknownTrbType)?
701             != T::TY
702         {
703             return Err(Error::CannotCastTrb);
704         }
705         T::from_slice(self.as_slice()).ok_or(Error::CannotCastTrb)
706     }
707 
checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T>708     fn checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T> {
709         if Trb::from_slice(self.as_slice())
710             .ok_or(Error::CannotCastTrb)?
711             .get_trb_type()
712             .map_err(Error::UnknownTrbType)?
713             != T::TY
714         {
715             return Err(Error::CannotCastTrb);
716         }
717         T::from_mut_slice(self.as_mut_slice()).ok_or(Error::CannotCastTrb)
718     }
719 }
720 
721 unsafe impl DataInit for Trb {}
722 unsafe impl DataInit for NormalTrb {}
723 unsafe impl DataInit for SetupStageTrb {}
724 unsafe impl DataInit for DataStageTrb {}
725 unsafe impl DataInit for StatusStageTrb {}
726 unsafe impl DataInit for IsochTrb {}
727 unsafe impl DataInit for LinkTrb {}
728 unsafe impl DataInit for EventDataTrb {}
729 unsafe impl DataInit for NoopTrb {}
730 unsafe impl DataInit for DisableSlotCommandTrb {}
731 unsafe impl DataInit for AddressDeviceCommandTrb {}
732 unsafe impl DataInit for ConfigureEndpointCommandTrb {}
733 unsafe impl DataInit for EvaluateContextCommandTrb {}
734 unsafe impl DataInit for ResetEndpointCommandTrb {}
735 unsafe impl DataInit for StopEndpointCommandTrb {}
736 unsafe impl DataInit for SetTRDequeuePointerCommandTrb {}
737 unsafe impl DataInit for ResetDeviceCommandTrb {}
738 unsafe impl DataInit for TransferEventTrb {}
739 unsafe impl DataInit for CommandCompletionEventTrb {}
740 unsafe impl DataInit for PortStatusChangeEventTrb {}
741 unsafe impl DataInit for EventRingSegmentTableEntry {}
742 unsafe impl DataInit for InputControlContext {}
743 unsafe impl DataInit for SlotContext {}
744 unsafe impl DataInit for EndpointContext {}
745 
746 unsafe impl DataInit for DeviceContext {}
747 unsafe impl DataInit for AddressedTrb {}
748 
749 unsafe impl TrbCast for Trb {}
750 unsafe impl TrbCast for NormalTrb {}
751 unsafe impl TrbCast for SetupStageTrb {}
752 unsafe impl TrbCast for DataStageTrb {}
753 unsafe impl TrbCast for StatusStageTrb {}
754 unsafe impl TrbCast for IsochTrb {}
755 unsafe impl TrbCast for LinkTrb {}
756 unsafe impl TrbCast for EventDataTrb {}
757 unsafe impl TrbCast for NoopTrb {}
758 unsafe impl TrbCast for DisableSlotCommandTrb {}
759 unsafe impl TrbCast for AddressDeviceCommandTrb {}
760 unsafe impl TrbCast for ConfigureEndpointCommandTrb {}
761 unsafe impl TrbCast for EvaluateContextCommandTrb {}
762 unsafe impl TrbCast for ResetEndpointCommandTrb {}
763 unsafe impl TrbCast for StopEndpointCommandTrb {}
764 unsafe impl TrbCast for SetTRDequeuePointerCommandTrb {}
765 unsafe impl TrbCast for ResetDeviceCommandTrb {}
766 unsafe impl TrbCast for TransferEventTrb {}
767 unsafe impl TrbCast for CommandCompletionEventTrb {}
768 unsafe impl TrbCast for PortStatusChangeEventTrb {}
769 
770 #[bitfield]
771 #[derive(Clone, Copy)]
772 pub struct EventRingSegmentTableEntry {
773     ring_segment_base_address: B64,
774     ring_segment_size: B16,
775     reserved2: B48,
776 }
777 
778 #[bitfield]
779 #[derive(Clone, Copy)]
780 pub struct InputControlContext {
781     // Xhci spec 6.2.5.1.
782     drop_context_flags: B32,
783     add_context_flags: B32,
784     reserved0: B32,
785     reserved1: B32,
786     reserved2: B32,
787     reserved3: B32,
788     reserved4: B32,
789     configuration_value: B8,
790     interface_number: B8,
791     alternate_setting: B8,
792     reserved5: B8,
793 }
794 
795 impl InputControlContext {
796     /// Get drop context flag.
drop_context_flag(&self, idx: u8) -> bool797     pub fn drop_context_flag(&self, idx: u8) -> bool {
798         (self.get_drop_context_flags() & (1 << idx)) != 0
799     }
800 
801     /// Get add context flag.
add_context_flag(&self, idx: u8) -> bool802     pub fn add_context_flag(&self, idx: u8) -> bool {
803         (self.get_add_context_flags() & (1 << idx)) != 0
804     }
805 }
806 
807 // Size of device context entries (SlotContext and EndpointContext).
808 pub const DEVICE_CONTEXT_ENTRY_SIZE: usize = 32usize;
809 
810 #[bitfield]
811 #[derive(Clone, Copy)]
812 pub struct SlotContext {
813     route_string: B20,
814     speed: B4,
815     reserved1: B1,
816     mtt: B1,
817     hub: B1,
818     context_entries: B5,
819     max_exit_latency: B16,
820     root_hub_port_number: B8,
821     num_ports: B8,
822     tt_hub_slot_id: B8,
823     tt_port_number: B8,
824     tt_think_time: B2,
825     reserved2: B4,
826     interrupter_target: B10,
827     usb_device_address: B8,
828     reserved3: B19,
829     slot_state: DeviceSlotState,
830     reserved4: B32,
831     reserved5: B32,
832     reserved6: B32,
833     reserved7: B32,
834 }
835 
836 #[bitfield]
837 #[derive(Clone, Copy)]
838 pub struct EndpointContext {
839     endpoint_state: EndpointState,
840     reserved1: B5,
841     mult: B2,
842     max_primary_streams: B5,
843     linear_stream_array: B1,
844     interval: B8,
845     max_esit_payload_hi: B8,
846     reserved2: B1,
847     error_count: B2,
848     endpoint_type: B3,
849     reserved3: B1,
850     host_initiate_disable: B1,
851     max_burst_size: B8,
852     max_packet_size: B16,
853     dequeue_cycle_state: bool,
854     reserved4: B3,
855     tr_dequeue_pointer: DequeuePtr,
856     average_trb_length: B16,
857     max_esit_payload_lo: B16,
858     reserved5: B32,
859     reserved6: B32,
860     reserved7: B32,
861 }
862 
863 /// Device context.
864 #[derive(Clone, Copy, Debug)]
865 pub struct DeviceContext {
866     pub slot_context: SlotContext,
867     pub endpoint_context: [EndpointContext; 31],
868 }
869 
870 /// POD struct associates a TRB with its address in guest memory.  This is
871 /// useful because transfer and command completion event TRBs must contain
872 /// pointers to the original TRB that generated the event.
873 #[derive(Clone, Copy, Debug, PartialEq)]
874 pub struct AddressedTrb {
875     pub trb: Trb,
876     pub gpa: u64,
877 }
878 
879 pub type TransferDescriptor = Vec<AddressedTrb>;
880 
881 #[cfg(test)]
882 mod tests {
883     use super::*;
884 
885     #[test]
check_struct_sizes()886     fn check_struct_sizes() {
887         assert_eq!(std::mem::size_of::<Trb>(), TRB_SIZE);
888         assert_eq!(std::mem::size_of::<NormalTrb>(), TRB_SIZE);
889         assert_eq!(std::mem::size_of::<SetupStageTrb>(), TRB_SIZE);
890         assert_eq!(std::mem::size_of::<DataStageTrb>(), TRB_SIZE);
891         assert_eq!(std::mem::size_of::<StatusStageTrb>(), TRB_SIZE);
892         assert_eq!(std::mem::size_of::<IsochTrb>(), TRB_SIZE);
893         assert_eq!(std::mem::size_of::<LinkTrb>(), TRB_SIZE);
894         assert_eq!(std::mem::size_of::<EventDataTrb>(), TRB_SIZE);
895         assert_eq!(std::mem::size_of::<NoopTrb>(), TRB_SIZE);
896         assert_eq!(std::mem::size_of::<DisableSlotCommandTrb>(), TRB_SIZE);
897         assert_eq!(std::mem::size_of::<AddressDeviceCommandTrb>(), TRB_SIZE);
898         assert_eq!(std::mem::size_of::<ConfigureEndpointCommandTrb>(), TRB_SIZE);
899         assert_eq!(std::mem::size_of::<EvaluateContextCommandTrb>(), TRB_SIZE);
900         assert_eq!(std::mem::size_of::<ResetEndpointCommandTrb>(), TRB_SIZE);
901         assert_eq!(std::mem::size_of::<StopEndpointCommandTrb>(), TRB_SIZE);
902         assert_eq!(
903             std::mem::size_of::<SetTRDequeuePointerCommandTrb>(),
904             TRB_SIZE
905         );
906         assert_eq!(std::mem::size_of::<ResetDeviceCommandTrb>(), TRB_SIZE);
907         assert_eq!(std::mem::size_of::<TransferEventTrb>(), TRB_SIZE);
908         assert_eq!(std::mem::size_of::<CommandCompletionEventTrb>(), TRB_SIZE);
909         assert_eq!(std::mem::size_of::<PortStatusChangeEventTrb>(), TRB_SIZE);
910 
911         assert_eq!(
912             std::mem::size_of::<EventRingSegmentTableEntry>(),
913             SEGMENT_TABLE_SIZE
914         );
915         assert_eq!(std::mem::size_of::<InputControlContext>(), 32);
916         assert_eq!(
917             std::mem::size_of::<SlotContext>(),
918             DEVICE_CONTEXT_ENTRY_SIZE
919         );
920         assert_eq!(
921             std::mem::size_of::<EndpointContext>(),
922             DEVICE_CONTEXT_ENTRY_SIZE
923         );
924         assert_eq!(
925             std::mem::size_of::<DeviceContext>(),
926             32 * DEVICE_CONTEXT_ENTRY_SIZE
927         );
928     }
929 }
930