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