diff options
Diffstat (limited to 'devices')
-rw-r--r-- | devices/src/usb/host_backend/host_backend_device_provider.rs | 6 | ||||
-rw-r--r-- | devices/src/usb/xhci/command_ring_controller.rs | 3 | ||||
-rw-r--r-- | devices/src/usb/xhci/device_slot.rs | 55 | ||||
-rw-r--r-- | devices/src/usb/xhci/ring_buffer.rs | 5 |
4 files changed, 28 insertions, 41 deletions
diff --git a/devices/src/usb/host_backend/host_backend_device_provider.rs b/devices/src/usb/host_backend/host_backend_device_provider.rs index 8d39d80..01fd84c 100644 --- a/devices/src/usb/host_backend/host_backend_device_provider.rs +++ b/devices/src/usb/host_backend/host_backend_device_provider.rs @@ -244,6 +244,12 @@ impl ProviderInner { } } }; + + // Resetting the device is used to make sure it is in a known state, but it may + // still function if the reset fails. + if let Err(e) = device_handle.reset() { + error!("failed to reset device after attach: {:?}", e); + } (device, device_handle) }; diff --git a/devices/src/usb/xhci/command_ring_controller.rs b/devices/src/usb/xhci/command_ring_controller.rs index 83582dd..6c84fc6 100644 --- a/devices/src/usb/xhci/command_ring_controller.rs +++ b/devices/src/usb/xhci/command_ring_controller.rs @@ -29,6 +29,7 @@ pub enum Error { StopEndpoint(DeviceSlotError), ConfigEndpoint(DeviceSlotError), SetAddress(DeviceSlotError), + SetDequeuePointer(DeviceSlotError), EvaluateContext(DeviceSlotError), DisableSlot(DeviceSlotError), ResetSlot(DeviceSlotError), @@ -48,6 +49,7 @@ impl Display for Error { StopEndpoint(e) => write!(f, "failed to stop endpoint: {}", e), ConfigEndpoint(e) => write!(f, "failed to config endpoint: {}", e), SetAddress(e) => write!(f, "failed to set address: {}", e), + SetDequeuePointer(e) => write!(f, "failed to set dequeue pointer: {}", e), EvaluateContext(e) => write!(f, "failed to evaluate context: {}", e), DisableSlot(e) => write!(f, "failed to disable slot: {}", e), ResetSlot(e) => write!(f, "failed to reset slot: {}", e), @@ -314,6 +316,7 @@ impl CommandRingTrbHandler { if valid_slot_id(slot_id) { self.slot(slot_id)? .set_tr_dequeue_ptr(endpoint_id, dequeue_ptr) + .map_err(Error::SetDequeuePointer)? } else { error!("stop endpoint trb has invalid slot id {}", slot_id); TrbCompletionCode::TrbError diff --git a/devices/src/usb/xhci/device_slot.rs b/devices/src/usb/xhci/device_slot.rs index ef58edb..d3d556a 100644 --- a/devices/src/usb/xhci/device_slot.rs +++ b/devices/src/usb/xhci/device_slot.rs @@ -514,23 +514,6 @@ impl DeviceSlot { if !self.enabled.load(Ordering::SeqCst) { return Ok(TrbCompletionCode::SlotNotEnabledError); } - - let device_context = self.get_device_context()?; - let state = device_context - .slot_context - .state() - .map_err(Error::GetSlotContextState)?; - if state == DeviceSlotState::Default - || state == DeviceSlotState::Addressed - || state == DeviceSlotState::Configured - { - error!( - "wrong context state on evaluate context. state = {:?}", - state - ); - return Ok(TrbCompletionCode::ContextStateError); - } - // TODO(jkwang) verify this // The spec has multiple contradictions about validating context parameters in sections // 4.6.7, 6.2.3.3. To keep things as simple as possible we do no further validation here. @@ -581,13 +564,6 @@ impl DeviceSlot { slot: &Arc<DeviceSlot>, mut callback: C, ) -> Result<()> { - let state = slot.state()?; - if state != DeviceSlotState::Addressed && state != DeviceSlotState::Configured { - error!("reset slot failed due to context state error {:?}", state); - return callback(TrbCompletionCode::ContextStateError) - .map_err(|_| Error::CallbackFailed); - } - let weak_s = Arc::downgrade(&slot); let auto_callback = RingBufferStopCallback::new(fallible_closure(fail_handle, move || -> Result<()> { @@ -650,20 +626,23 @@ impl DeviceSlot { } /// Set transfer ring dequeue pointer. - pub fn set_tr_dequeue_ptr(&self, endpoint_id: u8, ptr: u64) -> TrbCompletionCode { + pub fn set_tr_dequeue_ptr(&self, endpoint_id: u8, ptr: u64) -> Result<TrbCompletionCode> { if !valid_endpoint_id(endpoint_id) { error!("trb indexing wrong endpoint id"); - return TrbCompletionCode::TrbError; + return Ok(TrbCompletionCode::TrbError); } - let index = endpoint_id - 1; - match self.get_trc(index as usize) { + let index = (endpoint_id - 1) as usize; + match self.get_trc(index) { Some(trc) => { trc.set_dequeue_pointer(GuestAddress(ptr)); - TrbCompletionCode::Success + let mut ctx = self.get_device_context()?; + ctx.endpoint_context[index].set_tr_dequeue_pointer(ptr >> 4); + self.set_device_context(ctx)?; + Ok(TrbCompletionCode::Success) } None => { error!("set tr dequeue ptr failed due to no trc started"); - TrbCompletionCode::ContextStateError + Ok(TrbCompletionCode::ContextStateError) } } } @@ -718,9 +697,12 @@ impl DeviceSlot { } fn get_device_context(&self) -> Result<DeviceContext> { - self.mem + let ctx = self + .mem .read_obj_from_addr(self.get_device_context_addr()?) - .map_err(Error::ReadGuestMemory) + .map_err(Error::ReadGuestMemory)?; + usb_debug!("read device ctx: {:?}", ctx); + Ok(ctx) } fn set_device_context(&self, device_context: DeviceContext) -> Result<()> { @@ -768,15 +750,6 @@ impl DeviceSlot { Ok(GuestAddress(addr)) } - // Returns the current state of the device slot. - fn state(&self) -> Result<DeviceSlotState> { - let context = self.get_device_context()?; - context - .slot_context - .state() - .map_err(Error::GetSlotContextState) - } - fn set_state(&self, state: DeviceSlotState) -> Result<()> { let mut ctx = self.get_device_context()?; ctx.slot_context.set_state(state); diff --git a/devices/src/usb/xhci/ring_buffer.rs b/devices/src/usb/xhci/ring_buffer.rs index 5e2c570..72c9ec0 100644 --- a/devices/src/usb/xhci/ring_buffer.rs +++ b/devices/src/usb/xhci/ring_buffer.rs @@ -85,6 +85,11 @@ impl RingBuffer { } }; + usb_debug!( + "{}: adding trb to td {}", + self.name.as_str(), + addressed_trb.trb + ); td.push(addressed_trb); if !addressed_trb.trb.get_chain_bit().map_err(Error::TrbChain)? { usb_debug!("trb chain is false returning"); |