1 // Copyright 2019 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 super::command_ring_controller::{CommandRingController, CommandRingControllerError}; 6 use super::device_slot::{DeviceSlots, Error as DeviceSlotError}; 7 use super::interrupter::{Error as InterrupterError, Interrupter}; 8 use super::intr_resample_handler::IntrResampleHandler; 9 use super::ring_buffer_stop_cb::RingBufferStopCallback; 10 use super::usb_hub::UsbHub; 11 use super::xhci_backend_device_provider::XhciBackendDeviceProvider; 12 use super::xhci_regs::*; 13 use crate::usb::host_backend::host_backend_device_provider::HostBackendDeviceProvider; 14 use crate::utils::{Error as UtilsError, EventLoop, FailHandle}; 15 use std::fmt::{self, Display}; 16 use std::sync::Arc; 17 use sync::Mutex; 18 use sys_util::{error, EventFd, GuestAddress, GuestMemory}; 19 20 #[derive(Debug)] 21 pub enum Error { 22 StartEventLoop(UtilsError), 23 GetDeviceSlot(u8), 24 StartResampleHandler, 25 SendInterrupt(InterrupterError), 26 EnableInterrupter(InterrupterError), 27 SetModeration(InterrupterError), 28 SetupEventRing(InterrupterError), 29 SetEventHandlerBusy(InterrupterError), 30 StartProvider, 31 RingDoorbell(DeviceSlotError), 32 CreateCommandRingController(CommandRingControllerError), 33 ResetPort, 34 } 35 36 type Result<T> = std::result::Result<T, Error>; 37 38 impl Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 40 use self::Error::*; 41 42 match self { 43 StartEventLoop(e) => write!(f, "failed to start event loop: {}", e), 44 GetDeviceSlot(i) => write!(f, "failed to get device slot: {}", i), 45 StartResampleHandler => write!(f, "failed to start resample handler"), 46 SendInterrupt(e) => write!(f, "failed to send interrupter: {}", e), 47 EnableInterrupter(e) => write!(f, "failed to enable interrupter: {}", e), 48 SetModeration(e) => write!(f, "failed to set interrupter moderation: {}", e), 49 SetupEventRing(e) => write!(f, "failed to setup event ring: {}", e), 50 SetEventHandlerBusy(e) => write!(f, "failed to set event handler busy: {}", e), 51 StartProvider => write!(f, "failed to start backend provider"), 52 RingDoorbell(e) => write!(f, "failed to ring doorbell: {}", e), 53 CreateCommandRingController(e) => { 54 write!(f, "failed to create command ring controller: {}", e) 55 } 56 ResetPort => write!(f, "failed to reset port"), 57 } 58 } 59 } 60 61 /// xHCI controller implementation. 62 pub struct Xhci { 63 fail_handle: Arc<dyn FailHandle>, 64 regs: XhciRegs, 65 interrupter: Arc<Mutex<Interrupter>>, 66 command_ring_controller: Arc<CommandRingController>, 67 device_slots: DeviceSlots, 68 // resample handler and device provider only lives on EventLoop to handle corresponding events. 69 // By design, event loop only hold weak reference. We need to keep a strong reference here to 70 // keep it alive. 71 #[allow(dead_code)] 72 intr_resample_handler: Arc<IntrResampleHandler>, 73 #[allow(dead_code)] 74 device_provider: HostBackendDeviceProvider, 75 } 76 77 impl Xhci { 78 /// Create a new xHCI controller. new( fail_handle: Arc<dyn FailHandle>, mem: GuestMemory, device_provider: HostBackendDeviceProvider, irq_evt: EventFd, irq_resample_evt: EventFd, regs: XhciRegs, ) -> Result<Arc<Self>>79 pub fn new( 80 fail_handle: Arc<dyn FailHandle>, 81 mem: GuestMemory, 82 device_provider: HostBackendDeviceProvider, 83 irq_evt: EventFd, 84 irq_resample_evt: EventFd, 85 regs: XhciRegs, 86 ) -> Result<Arc<Self>> { 87 let (event_loop, _join_handle) = 88 EventLoop::start("xhci".to_string(), Some(fail_handle.clone())) 89 .map_err(Error::StartEventLoop)?; 90 let interrupter = Arc::new(Mutex::new(Interrupter::new(mem.clone(), irq_evt, ®s))); 91 let event_loop = Arc::new(event_loop); 92 let intr_resample_handler = 93 IntrResampleHandler::start(&event_loop, interrupter.clone(), irq_resample_evt) 94 .ok_or(Error::StartResampleHandler)?; 95 let hub = Arc::new(UsbHub::new(®s, interrupter.clone())); 96 97 let mut device_provider = device_provider; 98 device_provider 99 .start(fail_handle.clone(), event_loop.clone(), hub.clone()) 100 .map_err(|_| Error::StartProvider)?; 101 102 let device_slots = DeviceSlots::new( 103 fail_handle.clone(), 104 regs.dcbaap.clone(), 105 hub.clone(), 106 interrupter.clone(), 107 event_loop.clone(), 108 mem.clone(), 109 ); 110 let command_ring_controller = CommandRingController::new( 111 mem.clone(), 112 event_loop.clone(), 113 device_slots.clone(), 114 interrupter.clone(), 115 ) 116 .map_err(Error::CreateCommandRingController)?; 117 let xhci = Arc::new(Xhci { 118 fail_handle, 119 regs, 120 intr_resample_handler, 121 interrupter, 122 command_ring_controller, 123 device_slots, 124 device_provider, 125 }); 126 Self::init_reg_callbacks(&xhci); 127 Ok(xhci) 128 } 129 init_reg_callbacks(xhci: &Arc<Xhci>)130 fn init_reg_callbacks(xhci: &Arc<Xhci>) { 131 // All the callbacks will hold a weak reference to avoid memory leak. Thos weak upgrade 132 // should never fail. 133 let xhci_weak = Arc::downgrade(xhci); 134 xhci.regs.usbcmd.set_write_cb(move |val: u32| { 135 // All the weak reference upgrade should never fail. xhci hold reference to the 136 // registers, callback won't be invoked if xhci is gone. 137 let xhci = xhci_weak.upgrade().unwrap(); 138 let r = xhci.usbcmd_callback(val); 139 xhci.handle_register_callback_result(r, 0) 140 }); 141 142 let xhci_weak = Arc::downgrade(xhci); 143 xhci.regs.crcr.set_write_cb(move |val: u64| { 144 let xhci = xhci_weak.upgrade().unwrap(); 145 let r = xhci.crcr_callback(val); 146 xhci.handle_register_callback_result(r, 0) 147 }); 148 149 for i in 0..xhci.regs.portsc.len() { 150 let xhci_weak = Arc::downgrade(xhci); 151 xhci.regs.portsc[i].set_write_cb(move |val: u32| { 152 let xhci = xhci_weak.upgrade().unwrap(); 153 let r = xhci.portsc_callback(i as u32, val); 154 xhci.handle_register_callback_result(r, 0) 155 }); 156 } 157 158 for i in 0..xhci.regs.doorbells.len() { 159 let xhci_weak = Arc::downgrade(xhci); 160 xhci.regs.doorbells[i].set_write_cb(move |val: u32| { 161 let xhci = xhci_weak.upgrade().unwrap(); 162 let r = xhci.doorbell_callback(i as u32, val); 163 xhci.handle_register_callback_result(r, ()); 164 val 165 }); 166 } 167 168 let xhci_weak = Arc::downgrade(xhci); 169 xhci.regs.iman.set_write_cb(move |val: u32| { 170 let xhci = xhci_weak.upgrade().unwrap(); 171 let r = xhci.iman_callback(val); 172 xhci.handle_register_callback_result(r, ()); 173 val 174 }); 175 176 let xhci_weak = Arc::downgrade(xhci); 177 xhci.regs.imod.set_write_cb(move |val: u32| { 178 let xhci = xhci_weak.upgrade().unwrap(); 179 let r = xhci.imod_callback(val); 180 xhci.handle_register_callback_result(r, ()); 181 val 182 }); 183 184 let xhci_weak = Arc::downgrade(xhci); 185 xhci.regs.erstsz.set_write_cb(move |val: u32| { 186 let xhci = xhci_weak.upgrade().unwrap(); 187 let r = xhci.erstsz_callback(val); 188 xhci.handle_register_callback_result(r, ()); 189 val 190 }); 191 192 let xhci_weak = Arc::downgrade(xhci); 193 xhci.regs.erstba.set_write_cb(move |val: u64| { 194 let xhci = xhci_weak.upgrade().unwrap(); 195 let r = xhci.erstba_callback(val); 196 xhci.handle_register_callback_result(r, ()); 197 val 198 }); 199 200 let xhci_weak = Arc::downgrade(xhci); 201 xhci.regs.erdp.set_write_cb(move |val: u64| { 202 let xhci = xhci_weak.upgrade().unwrap(); 203 let r = xhci.erdp_callback(val); 204 xhci.handle_register_callback_result(r, ()); 205 val 206 }); 207 } 208 handle_register_callback_result<T>(&self, r: Result<T>, t: T) -> T209 fn handle_register_callback_result<T>(&self, r: Result<T>, t: T) -> T { 210 match r { 211 Ok(v) => v, 212 Err(e) => { 213 error!("xhci controller failed: {}", e); 214 self.fail_handle.fail(); 215 t 216 } 217 } 218 } 219 220 // Callback for usbcmd register write. usbcmd_callback(&self, value: u32) -> Result<u32>221 fn usbcmd_callback(&self, value: u32) -> Result<u32> { 222 if (value & USB_CMD_RESET) > 0 { 223 usb_debug!("xhci_controller: reset controller"); 224 self.reset()?; 225 return Ok(value & (!USB_CMD_RESET)); 226 } 227 228 if (value & USB_CMD_RUNSTOP) > 0 { 229 usb_debug!("xhci_controller: clear halt bits"); 230 self.regs.usbsts.clear_bits(USB_STS_HALTED); 231 } else { 232 usb_debug!("xhci_controller: halt device"); 233 self.halt()?; 234 self.regs.crcr.clear_bits(CRCR_COMMAND_RING_RUNNING); 235 } 236 237 // Enable interrupter if needed. 238 let enabled = (value & USB_CMD_INTERRUPTER_ENABLE) > 0 239 && (self.regs.iman.get_value() & IMAN_INTERRUPT_ENABLE) > 0; 240 usb_debug!("xhci_controller: interrupter enable?: {}", enabled); 241 self.interrupter 242 .lock() 243 .set_enabled(enabled) 244 .map_err(Error::EnableInterrupter)?; 245 Ok(value) 246 } 247 248 // Callback for crcr register write. crcr_callback(&self, value: u64) -> Result<u64>249 fn crcr_callback(&self, value: u64) -> Result<u64> { 250 usb_debug!("xhci_controller: write to crcr {:x}", value); 251 let value = if (self.regs.crcr.get_value() & CRCR_COMMAND_RING_RUNNING) == 0 { 252 self.command_ring_controller 253 .set_dequeue_pointer(GuestAddress(value & CRCR_COMMAND_RING_POINTER)); 254 self.command_ring_controller 255 .set_consumer_cycle_state((value & CRCR_RING_CYCLE_STATE) > 0); 256 value 257 } else { 258 error!("Write to crcr while command ring is running"); 259 self.regs.crcr.get_value() 260 }; 261 Ok(value) 262 } 263 264 // Callback for portsc register write. portsc_callback(&self, index: u32, value: u32) -> Result<u32>265 fn portsc_callback(&self, index: u32, value: u32) -> Result<u32> { 266 let mut value = value; 267 usb_debug!( 268 "xhci_controller: write to portsc index {} value {:x}", 269 index, 270 value 271 ); 272 let port_id = (index + 1) as u8; 273 // xHCI spec 4.19.5. Note: we might want to change this logic if we support USB 3.0. 274 if (value & PORTSC_PORT_RESET) > 0 || (value & PORTSC_WARM_PORT_RESET) > 0 { 275 self.device_slots 276 .reset_port(port_id) 277 .map_err(|_| Error::ResetPort)?; 278 value &= !PORTSC_PORT_LINK_STATE_MASK; 279 value &= !PORTSC_PORT_RESET; 280 value |= PORTSC_PORT_ENABLED; 281 value |= PORTSC_PORT_RESET_CHANGE; 282 self.interrupter 283 .lock() 284 .send_port_status_change_trb(port_id) 285 .map_err(Error::SendInterrupt)?; 286 } 287 Ok(value) 288 } 289 290 // Callback for doorbell register write. doorbell_callback(&self, index: u32, value: u32) -> Result<()>291 fn doorbell_callback(&self, index: u32, value: u32) -> Result<()> { 292 usb_debug!( 293 "xhci_controller: write to doorbell index {} value {:x}", 294 index, 295 value 296 ); 297 let target = (value & DOORBELL_TARGET) as u8; 298 let stream_id: u16 = (value >> DOORBELL_STREAM_ID_OFFSET) as u16; 299 if (self.regs.usbcmd.get_value() & USB_CMD_RUNSTOP) > 0 { 300 // First doorbell is for command ring. 301 if index == 0 { 302 if target != 0 || stream_id != 0 { 303 return Ok(()); 304 } 305 usb_debug!("doorbell to command ring"); 306 self.regs.crcr.set_bits(CRCR_COMMAND_RING_RUNNING); 307 self.command_ring_controller.start(); 308 } else { 309 usb_debug!("doorbell to device slot"); 310 self.device_slots 311 .slot(index as u8) 312 .ok_or(Error::GetDeviceSlot(index as u8))? 313 .ring_doorbell(target, stream_id) 314 .map_err(Error::RingDoorbell)?; 315 } 316 } 317 Ok(()) 318 } 319 320 // Callback for iman register write. iman_callback(&self, value: u32) -> Result<()>321 fn iman_callback(&self, value: u32) -> Result<()> { 322 usb_debug!("xhci_controller: write to iman {:x}", value); 323 let enabled = ((value & IMAN_INTERRUPT_ENABLE) > 0) 324 && ((self.regs.usbcmd.get_value() & USB_CMD_INTERRUPTER_ENABLE) > 0); 325 self.interrupter 326 .lock() 327 .set_enabled(enabled) 328 .map_err(Error::EnableInterrupter) 329 } 330 331 // Callback for imod register write. imod_callback(&self, value: u32) -> Result<()>332 fn imod_callback(&self, value: u32) -> Result<()> { 333 usb_debug!("xhci_controller: write to imod {:x}", value); 334 self.interrupter 335 .lock() 336 .set_moderation( 337 (value & IMOD_INTERRUPT_MODERATION_INTERVAL) as u16, 338 (value >> IMOD_INTERRUPT_MODERATION_COUNTER_OFFSET) as u16, 339 ) 340 .map_err(Error::SetModeration) 341 } 342 343 // Callback for erstsz register write. erstsz_callback(&self, value: u32) -> Result<()>344 fn erstsz_callback(&self, value: u32) -> Result<()> { 345 usb_debug!("xhci_controller: write to erstz {:x}", value); 346 self.interrupter 347 .lock() 348 .set_event_ring_seg_table_size((value & ERSTSZ_SEGMENT_TABLE_SIZE) as u16) 349 .map_err(Error::SetupEventRing) 350 } 351 352 // Callback for erstba register write. erstba_callback(&self, value: u64) -> Result<()>353 fn erstba_callback(&self, value: u64) -> Result<()> { 354 usb_debug!("xhci_controller: write to erstba {:x}", value); 355 self.interrupter 356 .lock() 357 .set_event_ring_seg_table_base_addr(GuestAddress( 358 value & ERSTBA_SEGMENT_TABLE_BASE_ADDRESS, 359 )) 360 .map_err(Error::SetupEventRing) 361 } 362 363 // Callback for erdp register write. erdp_callback(&self, value: u64) -> Result<()>364 fn erdp_callback(&self, value: u64) -> Result<()> { 365 usb_debug!("xhci_controller: write to erdp {:x}", value); 366 let mut interrupter = self.interrupter.lock(); 367 interrupter 368 .set_event_ring_dequeue_pointer(GuestAddress(value & ERDP_EVENT_RING_DEQUEUE_POINTER)) 369 .map_err(Error::SetupEventRing)?; 370 interrupter 371 .set_event_handler_busy((value & ERDP_EVENT_HANDLER_BUSY) > 0) 372 .map_err(Error::SetEventHandlerBusy) 373 } 374 reset(&self) -> Result<()>375 fn reset(&self) -> Result<()> { 376 self.regs.usbsts.set_bits(USB_STS_CONTROLLER_NOT_READY); 377 let usbsts = self.regs.usbsts.clone(); 378 self.device_slots.stop_all_and_reset(move || { 379 usbsts.clear_bits(USB_STS_CONTROLLER_NOT_READY); 380 }); 381 Ok(()) 382 } 383 halt(&self) -> Result<()>384 fn halt(&self) -> Result<()> { 385 let usbsts = self.regs.usbsts.clone(); 386 self.device_slots 387 .stop_all(RingBufferStopCallback::new(move || { 388 usbsts.set_bits(USB_STS_HALTED); 389 })); 390 Ok(()) 391 } 392 } 393