1use std::convert::TryInto;
6use std::fs::File;
7use std::io::Read;
8use std::io::Seek;
9use std::io::SeekFrom;
10use std::mem::size_of_val;
11use std::os::raw::c_int;
12use std::os::raw::c_uchar;
13use std::os::raw::c_uint;
14use std::os::raw::c_void;
15use std::sync::Arc;
16use std::sync::Weak;
17
18use base::debug;
19use base::error;
20use base::handle_eintr_errno;
21use base::warn;
22use base::AsRawDescriptor;
23use base::IoctlNr;
24use base::MappedRegion;
25use base::MemoryMapping;
26use base::MemoryMappingBuilder;
27use base::Protection;
28use base::RawDescriptor;
29use data_model::vec_with_array_field;
30use libc::EAGAIN;
31use libc::EINVAL;
32use libc::ENODEV;
33use libc::ENOENT;
34use libc::EPIPE;
35use sync::Mutex;
36
37use crate::control_request_type;
38use crate::descriptor;
39use crate::ConfigDescriptorTree;
40use crate::ControlRequestDataPhaseTransferDirection;
41use crate::ControlRequestRecipient;
42use crate::ControlRequestType;
43use crate::DeviceDescriptor;
44use crate::DeviceDescriptorTree;
45use crate::DeviceSpeed;
46use crate::Error;
47use crate::Result;
48use crate::StandardControlRequest;
49
50const MMAP_SIZE: usize = 1024 * 1024;
52
53struct ManagedDmaBuffer {
55 buf: MemoryMapping,
57 used: Option<Arc<Mutex<DmaBuffer>>>,
59}
60
61pub struct DmaBuffer {
63 addr: u64,
65 size: usize,
67}
68
69impl DmaBuffer {
70 pub fn address(&mut self) -> *mut c_void {
71 self.addr as *mut c_void
72 }
73
74 pub fn size(&self) -> usize {
75 self.size
76 }
77
78 pub fn as_slice(&self) -> &[u8] {
79 unsafe { std::slice::from_raw_parts(self.addr as *const u8, self.size) }
82 }
83
84 pub fn as_mut_slice(&mut self) -> &mut [u8] {
85 unsafe { std::slice::from_raw_parts_mut(self.addr as *mut u8, self.size) }
88 }
89}
90
91#[derive(Clone)]
93pub enum TransferBuffer {
94 Vector(Vec<u8>),
95 Dma(Weak<Mutex<DmaBuffer>>),
96}
97
98impl TransferBuffer {
99 pub fn address(&mut self) -> Option<*mut c_void> {
100 match self {
101 TransferBuffer::Vector(v) => Some(v.as_mut_ptr() as *mut c_void),
102 TransferBuffer::Dma(buf) => buf.upgrade().map(|buf| buf.lock().address()),
103 }
104 }
105 pub fn size(&self) -> Option<usize> {
106 match self {
107 TransferBuffer::Vector(v) => Some(v.len()),
108 TransferBuffer::Dma(buf) => buf.upgrade().map(|buf| buf.lock().size()),
109 }
110 }
111}
112
113pub struct Device {
115 fd: Arc<File>,
116 device_descriptor_tree: DeviceDescriptorTree,
117 dma_buffer: Option<ManagedDmaBuffer>,
118}
119
120pub struct Transfer {
123 urb: Vec<usb_sys::usbdevfs_urb>,
126 pub buffer: TransferBuffer,
127 callback: Option<Box<dyn Fn(Transfer) + Send + Sync>>,
128}
129
130pub struct TransferHandle {
135 weak_transfer: std::sync::Weak<Transfer>,
136 fd: std::sync::Weak<File>,
137}
138
139#[derive(PartialEq, Eq, Clone, Copy)]
140pub enum TransferStatus {
141 Completed,
142 Error,
143 Cancelled,
144 NoDevice,
145 Stalled,
146}
147
148impl Device {
149 pub fn new(mut fd: File) -> Result<Self> {
152 fd.seek(SeekFrom::Start(0)).map_err(Error::DescriptorRead)?;
153 let mut descriptor_data = Vec::new();
154 fd.read_to_end(&mut descriptor_data)
155 .map_err(Error::DescriptorRead)?;
156 let device_descriptor_tree = descriptor::parse_usbfs_descriptors(&descriptor_data)?;
157
158 let mut device = Device {
159 fd: Arc::new(fd),
160 device_descriptor_tree,
161 dma_buffer: None,
162 };
163
164 let map = MemoryMappingBuilder::new(MMAP_SIZE)
165 .from_file(&device.fd)
166 .protection(Protection::read_write())
167 .build();
168 match map {
169 Ok(map) => {
170 device.dma_buffer = Some(ManagedDmaBuffer {
171 buf: map,
172 used: None,
173 });
174 }
175 Err(e) => {
176 warn!(
178 "mmap() failed. User-provided buffer will be used for data transfer. {}",
179 e
180 );
181 }
182 }
183 Ok(device)
184 }
185
186 pub fn fd(&self) -> Arc<File> {
187 self.fd.clone()
188 }
189
190 unsafe fn ioctl(&self, nr: IoctlNr) -> Result<i32> {
191 let ret = handle_eintr_errno!(base::ioctl(&*self.fd, nr));
192 if ret < 0 {
193 return Err(Error::IoctlFailed(nr, base::Error::last()));
194 }
195 Ok(ret)
196 }
197
198 unsafe fn ioctl_with_ref<T>(&self, nr: IoctlNr, arg: &T) -> Result<i32> {
199 let ret = handle_eintr_errno!(base::ioctl_with_ref(&*self.fd, nr, arg));
200 if ret < 0 {
201 return Err(Error::IoctlFailed(nr, base::Error::last()));
202 }
203 Ok(ret)
204 }
205
206 unsafe fn ioctl_with_mut_ref<T>(&self, nr: IoctlNr, arg: &mut T) -> Result<i32> {
207 let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(&*self.fd, nr, arg));
208 if ret < 0 {
209 return Err(Error::IoctlFailed(nr, base::Error::last()));
210 }
211 Ok(ret)
212 }
213
214 unsafe fn ioctl_with_mut_ptr<T>(&self, nr: IoctlNr, arg: *mut T) -> Result<i32> {
215 let ret = handle_eintr_errno!(base::ioctl_with_mut_ptr(&*self.fd, nr, arg));
216 if ret < 0 {
217 return Err(Error::IoctlFailed(nr, base::Error::last()));
218 }
219 Ok(ret)
220 }
221
222 pub fn reserve_dma_buffer(&mut self, size: usize) -> Result<Weak<Mutex<DmaBuffer>>> {
223 if let Some(managed) = &mut self.dma_buffer {
224 if managed.used.is_none() {
225 let buf = Arc::new(Mutex::new(DmaBuffer {
226 addr: managed.buf.as_ptr() as u64,
227 size,
228 }));
229 let ret = Ok(Arc::downgrade(&buf));
230 managed.used = Some(buf);
231 return ret;
232 }
233 }
234 Err(Error::GetDmaBufferFailed(size))
235 }
236
237 pub fn release_dma_buffer(&mut self, dmabuf: Weak<Mutex<DmaBuffer>>) -> Result<()> {
238 if let Some(managed) = &mut self.dma_buffer {
239 if let Some(released) = dmabuf.upgrade() {
240 let addr = { released.lock().address() as u64 };
241 if let Some(lent) = &managed.used {
242 if lent.lock().addr == addr {
243 managed.used = None;
244 return Ok(());
245 }
246 }
247 }
248 }
249 Err(Error::ReleaseDmaBufferFailed)
250 }
251
252 pub fn submit_transfer(&mut self, transfer: Transfer) -> Result<TransferHandle> {
256 let mut rc_transfer = Arc::new(transfer);
257
258 let raw_transfer = (&*rc_transfer) as *const Transfer as usize;
265 match Arc::get_mut(&mut rc_transfer) {
266 Some(t) => t.urb_mut().usercontext = raw_transfer,
267 None => {
268 return Err(Error::RcGetMutFailed);
271 }
272 }
273 let _ = Arc::into_raw(rc_transfer.clone());
274
275 let urb_ptr = rc_transfer.urb.as_ptr() as *mut usb_sys::usbdevfs_urb;
276
277 unsafe {
281 self.ioctl_with_mut_ptr(usb_sys::USBDEVFS_SUBMITURB, urb_ptr)?;
282 }
283
284 let weak_transfer = Arc::downgrade(&rc_transfer);
285
286 Ok(TransferHandle {
287 weak_transfer,
288 fd: Arc::downgrade(&self.fd),
289 })
290 }
291
292 pub fn poll_transfers(&mut self) -> Result<()> {
295 loop {
297 let mut urb_ptr: *mut usb_sys::usbdevfs_urb = std::ptr::null_mut();
298 let result =
299 unsafe { self.ioctl_with_mut_ref(usb_sys::USBDEVFS_REAPURBNDELAY, &mut urb_ptr) };
302 match result {
303 Err(Error::IoctlFailed(_nr, e)) if e.errno() == EAGAIN => break,
305 Err(e) => return Err(e),
306 Ok(_) => {}
307 }
308
309 if urb_ptr.is_null() {
310 break;
311 }
312
313 let rc_transfer: Arc<Transfer> =
314 unsafe { Arc::from_raw((*urb_ptr).usercontext as *const Transfer) };
318
319 let mut transfer = Arc::try_unwrap(rc_transfer).map_err(|_| Error::RcUnwrapFailed)?;
322
323 let dmabuf = match &mut transfer.buffer {
324 TransferBuffer::Dma(buf) => Some(buf.clone()),
325 TransferBuffer::Vector(_) => None,
326 };
327
328 if let Some(cb) = transfer.callback.take() {
329 cb(transfer);
330 }
331
332 if let Some(dmabuf) = dmabuf {
333 if self.release_dma_buffer(dmabuf).is_err() {
334 warn!("failed to release dma buffer");
335 }
336 }
337 }
338
339 Ok(())
340 }
341
342 pub fn reset(&self) -> Result<()> {
344 let vid = self.device_descriptor_tree.idVendor;
347 let pid = self.device_descriptor_tree.idProduct;
348 match (vid, pid) {
349 (0x1a6e, 0x089a) => (),
350 _ => return Ok(()),
351 }
352
353 let result = unsafe { self.ioctl(usb_sys::USBDEVFS_RESET) };
356
357 if let Err(Error::IoctlFailed(_nr, errno_err)) = result {
358 if errno_err.errno() == libc::ENODEV {
361 return Ok(());
362 }
363 }
364
365 result?;
366 Ok(())
367 }
368
369 pub fn claim_interface(&self, interface_number: u8) -> Result<()> {
371 let disconnect_claim = usb_sys::usbdevfs_disconnect_claim {
372 interface: interface_number.into(),
373 flags: 0,
374 driver: [0u8; 256],
375 };
376 unsafe {
380 self.ioctl_with_ref(usb_sys::USBDEVFS_DISCONNECT_CLAIM, &disconnect_claim)?;
381 }
382
383 Ok(())
384 }
385
386 pub fn release_interface(&self, interface_number: u8) -> Result<()> {
388 let ifnum: c_uint = interface_number.into();
389 unsafe {
393 self.ioctl_with_ref(usb_sys::USBDEVFS_RELEASEINTERFACE, &ifnum)?;
394 }
395
396 Ok(())
397 }
398
399 pub fn set_interface_alt_setting(
401 &self,
402 interface_number: u8,
403 alternative_setting: u8,
404 ) -> Result<()> {
405 let setinterface = usb_sys::usbdevfs_setinterface {
406 interface: interface_number.into(),
407 altsetting: alternative_setting.into(),
408 };
409 unsafe {
413 self.ioctl_with_ref(usb_sys::USBDEVFS_SETINTERFACE, &setinterface)?;
414 }
415 Ok(())
416 }
417
418 pub fn set_active_configuration(&mut self, config: u8) -> Result<()> {
420 let config: c_int = config.into();
421 unsafe {
425 self.ioctl_with_ref(usb_sys::USBDEVFS_SETCONFIGURATION, &config)?;
426 }
427
428 Ok(())
429 }
430
431 pub fn get_device_descriptor(&self) -> Result<DeviceDescriptor> {
433 Ok(*self.device_descriptor_tree)
434 }
435
436 pub fn get_device_descriptor_tree(&self) -> &DeviceDescriptorTree {
437 &self.device_descriptor_tree
438 }
439
440 pub fn get_config_descriptor(&self, config: u8) -> Result<ConfigDescriptorTree> {
442 match self.device_descriptor_tree.get_config_descriptor(config) {
443 Some(config_descriptor) => Ok(config_descriptor.clone()),
444 None => Err(Error::NoSuchDescriptor),
445 }
446 }
447
448 pub fn get_config_descriptor_by_index(&self, config_index: u8) -> Result<ConfigDescriptorTree> {
451 match self
452 .device_descriptor_tree
453 .get_config_descriptor_by_index(config_index)
454 {
455 Some(config_descriptor) => Ok(config_descriptor.clone()),
456 None => Err(Error::NoSuchDescriptor),
457 }
458 }
459
460 pub fn get_active_configuration(&self) -> Result<u8> {
462 if self.device_descriptor_tree.bNumConfigurations == 1 {
465 if let Some(config_descriptor) = self
466 .device_descriptor_tree
467 .get_config_descriptor_by_index(0)
468 {
469 return Ok(config_descriptor.bConfigurationValue);
470 }
471 }
472
473 let mut active_config: u8 = 0;
475 let ctrl_transfer = usb_sys::usbdevfs_ctrltransfer {
476 bRequestType: control_request_type(
477 ControlRequestType::Standard,
478 ControlRequestDataPhaseTransferDirection::DeviceToHost,
479 ControlRequestRecipient::Device,
480 ),
481 bRequest: StandardControlRequest::GetConfiguration as u8,
482 wValue: 0,
483 wIndex: 0,
484 wLength: size_of_val(&active_config) as u16,
485 timeout: 5000, data: &mut active_config as *mut u8 as *mut c_void,
487 };
488 unsafe {
492 self.ioctl_with_ref(usb_sys::USBDEVFS_CONTROL, &ctrl_transfer)?;
493 }
494 Ok(active_config)
495 }
496
497 pub fn get_num_configurations(&self) -> u8 {
499 self.device_descriptor_tree.bNumConfigurations
500 }
501
502 pub fn clear_halt(&self, ep_addr: u8) -> Result<()> {
504 let endpoint: c_uint = ep_addr.into();
505 unsafe {
509 self.ioctl_with_ref(usb_sys::USBDEVFS_CLEAR_HALT, &endpoint)?;
510 }
511
512 Ok(())
513 }
514
515 pub fn get_speed(&self) -> Result<Option<DeviceSpeed>> {
517 let speed = unsafe { self.ioctl(usb_sys::USBDEVFS_GET_SPEED) }?;
519 match speed {
520 1 => Ok(Some(DeviceSpeed::Low)), 2 => Ok(Some(DeviceSpeed::Full)), 3 => Ok(Some(DeviceSpeed::High)), 4 => Ok(Some(DeviceSpeed::High)), 5 => Ok(Some(DeviceSpeed::Super)), 6 => Ok(Some(DeviceSpeed::SuperPlus)), _ => {
527 error!("unexpected speed: {:?}", speed);
528 Ok(None)
529 }
530 }
531 }
532
533 pub fn alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()> {
535 let mut streams = vec_with_array_field::<usb_sys::usbdevfs_streams, c_uchar>(1);
536 streams[0].num_streams = num_streams as c_uint;
537 streams[0].num_eps = 1 as c_uint;
538 let eps = unsafe { streams[0].eps.as_mut_slice(1) };
541 eps[0] = ep as c_uchar;
542 unsafe {
546 self.ioctl_with_ref(usb_sys::USBDEVFS_ALLOC_STREAMS, &streams[0])?;
547 }
548 Ok(())
549 }
550
551 pub fn free_streams(&self, ep: u8) -> Result<()> {
553 let mut streams = vec_with_array_field::<usb_sys::usbdevfs_streams, c_uchar>(1);
554 streams[0].num_eps = 1 as c_uint;
555 let eps = unsafe { streams[0].eps.as_mut_slice(1) };
558 eps[0] = ep as c_uchar;
559 unsafe {
563 self.ioctl_with_ref(usb_sys::USBDEVFS_FREE_STREAMS, &streams[0])?;
564 }
565 Ok(())
566 }
567}
568
569impl AsRawDescriptor for Device {
570 fn as_raw_descriptor(&self) -> RawDescriptor {
571 self.fd.as_raw_descriptor()
572 }
573}
574
575impl Transfer {
576 fn urb(&self) -> &usb_sys::usbdevfs_urb {
577 &self.urb[0]
580 }
581
582 fn urb_mut(&mut self) -> &mut usb_sys::usbdevfs_urb {
583 &mut self.urb[0]
584 }
585
586 fn new(
587 transfer_type: u8,
588 endpoint: u8,
589 buffer: TransferBuffer,
590 iso_packets: &[usb_sys::usbdevfs_iso_packet_desc],
591 ) -> Result<Transfer> {
592 let mut transfer = Transfer {
593 urb: vec_with_array_field::<usb_sys::usbdevfs_urb, usb_sys::usbdevfs_iso_packet_desc>(
594 iso_packets.len(),
595 ),
596 buffer,
597 callback: None,
598 };
599
600 transfer.urb_mut().urb_type = transfer_type;
601 transfer.urb_mut().endpoint = endpoint;
602 transfer.urb_mut().buffer = transfer.buffer.address().ok_or(Error::InvalidBuffer)?;
603 transfer.urb_mut().buffer_length = transfer
604 .buffer
605 .size()
606 .ok_or(Error::InvalidBuffer)?
607 .try_into()
608 .map_err(Error::InvalidBufferLength)?;
609
610 let iso_frame_desc = unsafe {
614 transfer
615 .urb_mut()
616 .iso_frame_desc
617 .as_mut_slice(iso_packets.len())
618 };
619 iso_frame_desc.copy_from_slice(iso_packets);
620
621 Ok(transfer)
622 }
623
624 pub fn new_control(buffer: TransferBuffer) -> Result<Transfer> {
626 let endpoint = 0;
627 Self::new(usb_sys::USBDEVFS_URB_TYPE_CONTROL, endpoint, buffer, &[])
628 }
629
630 pub fn new_interrupt(endpoint: u8, buffer: TransferBuffer) -> Result<Transfer> {
632 Self::new(usb_sys::USBDEVFS_URB_TYPE_INTERRUPT, endpoint, buffer, &[])
633 }
634
635 pub fn new_bulk(
637 endpoint: u8,
638 buffer: TransferBuffer,
639 stream_id: Option<u16>,
640 ) -> Result<Transfer> {
641 let mut transfer = Self::new(usb_sys::USBDEVFS_URB_TYPE_BULK, endpoint, buffer, &[])?;
642 if let Some(stream_id) = stream_id {
643 transfer.urb_mut().number_of_packets_or_stream_id = stream_id as u32;
644 }
645 Ok(transfer)
646 }
647
648 pub fn new_isochronous(
650 endpoint: u8,
651 buffer: TransferBuffer,
652 packet_size: u32,
653 ) -> Result<Transfer> {
654 let buffer_size: u32 = buffer
655 .size()
656 .ok_or(Error::InvalidBuffer)?
657 .try_into()
658 .map_err(Error::InvalidBufferLength)?;
659 let count = match buffer_size
662 .checked_add(packet_size)
663 .and_then(|s| s.checked_sub(1))
664 .and_then(|s| s.checked_div(packet_size))
665 {
666 Some(0) | None => {
667 error!("invalid ISOC packet count: buffer_size={buffer_size}, packet_size={packet_size}");
668 return Err(Error::InvalidISOCPacketCount);
669 }
670 Some(q) => q,
671 };
672
673 let mut iso_packets = vec![
674 usb_sys::usbdevfs_iso_packet_desc {
675 length: packet_size,
676 actual_length: 0,
677 status: 0,
678 };
679 count as usize
680 ];
681 let last_entry = iso_packets
682 .last_mut()
683 .expect("there should be at least one entry for ISOC packet");
684 last_entry.length = buffer_size - packet_size * (count - 1);
685
686 let mut transfer = Self::new(
687 usb_sys::USBDEVFS_URB_TYPE_ISO,
688 endpoint,
689 buffer,
690 &iso_packets,
691 )?;
692 transfer.urb_mut().number_of_packets_or_stream_id = count;
693 transfer.urb_mut().flags = usb_sys::USBDEVFS_URB_ISO_ASAP;
694 Ok(transfer)
695 }
696
697 pub fn status(&self) -> TransferStatus {
699 let status = self.urb().status;
700 if status == 0 {
701 TransferStatus::Completed
702 } else if status == -ENODEV {
703 TransferStatus::NoDevice
704 } else if status == -ENOENT {
705 TransferStatus::Cancelled
706 } else if status == -EPIPE {
707 TransferStatus::Stalled
708 } else {
709 TransferStatus::Error
710 }
711 }
712
713 pub fn actual_length(&self) -> usize {
716 self.urb().actual_length as usize
717 }
718
719 pub fn set_callback<C: 'static + Fn(Transfer) + Send + Sync>(&mut self, cb: C) {
721 self.callback = Some(Box::new(cb));
722 }
723}
724
725impl TransferHandle {
726 pub fn cancel(&self) -> Result<()> {
730 let rc_transfer = match self.weak_transfer.upgrade() {
731 None => return Err(Error::TransferAlreadyCompleted),
732 Some(rc_transfer) => rc_transfer,
733 };
734
735 let urb_ptr = rc_transfer.urb.as_ptr() as *mut usb_sys::usbdevfs_urb;
736 let fd = match self.fd.upgrade() {
737 None => return Err(Error::NoDevice),
738 Some(fd) => fd,
739 };
740
741 if unsafe {
745 handle_eintr_errno!(base::ioctl_with_mut_ptr(
746 &*fd,
747 usb_sys::USBDEVFS_DISCARDURB,
748 urb_ptr
749 ))
750 } < 0
751 {
752 let error = base::Error::last();
755 if error.errno() == EINVAL {
756 debug!("URB not found: already completed or invalid pointer to URB");
757 } else {
758 return Err(Error::IoctlFailed(usb_sys::USBDEVFS_DISCARDURB, error));
759 }
760 }
761
762 Ok(())
763 }
764}