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::error;
19use base::handle_eintr_errno;
20use base::warn;
21use base::AsRawDescriptor;
22use base::IoctlNr;
23use base::MappedRegion;
24use base::MemoryMapping;
25use base::MemoryMappingBuilder;
26use base::Protection;
27use base::RawDescriptor;
28use data_model::vec_with_array_field;
29use libc::EAGAIN;
30use libc::ENODEV;
31use libc::ENOENT;
32use libc::EPIPE;
33use sync::Mutex;
34
35use crate::control_request_type;
36use crate::descriptor;
37use crate::ConfigDescriptorTree;
38use crate::ControlRequestDataPhaseTransferDirection;
39use crate::ControlRequestRecipient;
40use crate::ControlRequestType;
41use crate::DeviceDescriptor;
42use crate::DeviceDescriptorTree;
43use crate::DeviceSpeed;
44use crate::Error;
45use crate::Result;
46use crate::StandardControlRequest;
47
48const MMAP_SIZE: usize = 1024 * 1024;
50
51struct ManagedDmaBuffer {
53 buf: MemoryMapping,
55 used: Option<Arc<Mutex<DmaBuffer>>>,
57}
58
59pub struct DmaBuffer {
61 addr: u64,
63 size: usize,
65}
66
67impl DmaBuffer {
68 pub fn address(&mut self) -> *mut c_void {
69 self.addr as *mut c_void
70 }
71
72 pub fn size(&self) -> usize {
73 self.size
74 }
75
76 pub fn as_slice(&self) -> &[u8] {
77 unsafe { std::slice::from_raw_parts(self.addr as *const u8, self.size) }
80 }
81
82 pub fn as_mut_slice(&mut self) -> &mut [u8] {
83 unsafe { std::slice::from_raw_parts_mut(self.addr as *mut u8, self.size) }
86 }
87}
88
89#[derive(Clone)]
91pub enum TransferBuffer {
92 Vector(Vec<u8>),
93 Dma(Weak<Mutex<DmaBuffer>>),
94}
95
96impl TransferBuffer {
97 pub fn address(&mut self) -> Option<*mut c_void> {
98 match self {
99 TransferBuffer::Vector(v) => Some(v.as_mut_ptr() as *mut c_void),
100 TransferBuffer::Dma(buf) => buf.upgrade().map(|buf| buf.lock().address()),
101 }
102 }
103 pub fn size(&self) -> Option<usize> {
104 match self {
105 TransferBuffer::Vector(v) => Some(v.len()),
106 TransferBuffer::Dma(buf) => buf.upgrade().map(|buf| buf.lock().size()),
107 }
108 }
109}
110
111pub struct Device {
113 fd: Arc<File>,
114 device_descriptor_tree: DeviceDescriptorTree,
115 dma_buffer: Option<ManagedDmaBuffer>,
116}
117
118pub struct Transfer {
121 urb: Vec<usb_sys::usbdevfs_urb>,
124 pub buffer: TransferBuffer,
125 callback: Option<Box<dyn Fn(Transfer) + Send + Sync>>,
126}
127
128pub struct TransferHandle {
133 weak_transfer: std::sync::Weak<Transfer>,
134 fd: std::sync::Weak<File>,
135}
136
137#[derive(PartialEq, Eq, Clone, Copy)]
138pub enum TransferStatus {
139 Completed,
140 Error,
141 Cancelled,
142 NoDevice,
143 Stalled,
144}
145
146impl Device {
147 pub fn new(mut fd: File) -> Result<Self> {
150 fd.seek(SeekFrom::Start(0)).map_err(Error::DescriptorRead)?;
151 let mut descriptor_data = Vec::new();
152 fd.read_to_end(&mut descriptor_data)
153 .map_err(Error::DescriptorRead)?;
154 let device_descriptor_tree = descriptor::parse_usbfs_descriptors(&descriptor_data)?;
155
156 let mut device = Device {
157 fd: Arc::new(fd),
158 device_descriptor_tree,
159 dma_buffer: None,
160 };
161
162 let map = MemoryMappingBuilder::new(MMAP_SIZE)
163 .from_file(&device.fd)
164 .protection(Protection::read_write())
165 .build();
166 match map {
167 Ok(map) => {
168 device.dma_buffer = Some(ManagedDmaBuffer {
169 buf: map,
170 used: None,
171 });
172 }
173 Err(e) => {
174 warn!(
176 "mmap() failed. User-provided buffer will be used for data transfer. {}",
177 e
178 );
179 }
180 }
181 Ok(device)
182 }
183
184 pub fn fd(&self) -> Arc<File> {
185 self.fd.clone()
186 }
187
188 unsafe fn ioctl(&self, nr: IoctlNr) -> Result<i32> {
189 let ret = handle_eintr_errno!(base::ioctl(&*self.fd, nr));
190 if ret < 0 {
191 return Err(Error::IoctlFailed(nr, base::Error::last()));
192 }
193 Ok(ret)
194 }
195
196 unsafe fn ioctl_with_ref<T>(&self, nr: IoctlNr, arg: &T) -> Result<i32> {
197 let ret = handle_eintr_errno!(base::ioctl_with_ref(&*self.fd, nr, arg));
198 if ret < 0 {
199 return Err(Error::IoctlFailed(nr, base::Error::last()));
200 }
201 Ok(ret)
202 }
203
204 unsafe fn ioctl_with_mut_ref<T>(&self, nr: IoctlNr, arg: &mut T) -> Result<i32> {
205 let ret = handle_eintr_errno!(base::ioctl_with_mut_ref(&*self.fd, nr, arg));
206 if ret < 0 {
207 return Err(Error::IoctlFailed(nr, base::Error::last()));
208 }
209 Ok(ret)
210 }
211
212 unsafe fn ioctl_with_mut_ptr<T>(&self, nr: IoctlNr, arg: *mut T) -> Result<i32> {
213 let ret = handle_eintr_errno!(base::ioctl_with_mut_ptr(&*self.fd, nr, arg));
214 if ret < 0 {
215 return Err(Error::IoctlFailed(nr, base::Error::last()));
216 }
217 Ok(ret)
218 }
219
220 pub fn reserve_dma_buffer(&mut self, size: usize) -> Result<Weak<Mutex<DmaBuffer>>> {
221 if let Some(managed) = &mut self.dma_buffer {
222 if managed.used.is_none() {
223 let buf = Arc::new(Mutex::new(DmaBuffer {
224 addr: managed.buf.as_ptr() as u64,
225 size,
226 }));
227 let ret = Ok(Arc::downgrade(&buf));
228 managed.used = Some(buf);
229 return ret;
230 }
231 }
232 Err(Error::GetDmaBufferFailed(size))
233 }
234
235 pub fn release_dma_buffer(&mut self, dmabuf: Weak<Mutex<DmaBuffer>>) -> Result<()> {
236 if let Some(managed) = &mut self.dma_buffer {
237 if let Some(released) = dmabuf.upgrade() {
238 let addr = { released.lock().address() as u64 };
239 if let Some(lent) = &managed.used {
240 if lent.lock().addr == addr {
241 managed.used = None;
242 return Ok(());
243 }
244 }
245 }
246 }
247 Err(Error::ReleaseDmaBufferFailed)
248 }
249
250 pub fn submit_transfer(&mut self, transfer: Transfer) -> Result<TransferHandle> {
254 let mut rc_transfer = Arc::new(transfer);
255
256 let raw_transfer = (&*rc_transfer) as *const Transfer as usize;
263 match Arc::get_mut(&mut rc_transfer) {
264 Some(t) => t.urb_mut().usercontext = raw_transfer,
265 None => {
266 return Err(Error::RcGetMutFailed);
269 }
270 }
271 let _ = Arc::into_raw(rc_transfer.clone());
272
273 let urb_ptr = rc_transfer.urb.as_ptr() as *mut usb_sys::usbdevfs_urb;
274
275 unsafe {
279 self.ioctl_with_mut_ptr(usb_sys::USBDEVFS_SUBMITURB, urb_ptr)?;
280 }
281
282 let weak_transfer = Arc::downgrade(&rc_transfer);
283
284 Ok(TransferHandle {
285 weak_transfer,
286 fd: Arc::downgrade(&self.fd),
287 })
288 }
289
290 pub fn poll_transfers(&mut self) -> Result<()> {
293 loop {
295 let mut urb_ptr: *mut usb_sys::usbdevfs_urb = std::ptr::null_mut();
296 let result =
297 unsafe { self.ioctl_with_mut_ref(usb_sys::USBDEVFS_REAPURBNDELAY, &mut urb_ptr) };
300 match result {
301 Err(Error::IoctlFailed(_nr, e)) if e.errno() == EAGAIN => break,
303 Err(e) => return Err(e),
304 Ok(_) => {}
305 }
306
307 if urb_ptr.is_null() {
308 break;
309 }
310
311 let rc_transfer: Arc<Transfer> =
312 unsafe { Arc::from_raw((*urb_ptr).usercontext as *const Transfer) };
316
317 let mut transfer = Arc::try_unwrap(rc_transfer).map_err(|_| Error::RcUnwrapFailed)?;
320
321 let dmabuf = match &mut transfer.buffer {
322 TransferBuffer::Dma(buf) => Some(buf.clone()),
323 TransferBuffer::Vector(_) => None,
324 };
325
326 if let Some(cb) = transfer.callback.take() {
327 cb(transfer);
328 }
329
330 if let Some(dmabuf) = dmabuf {
331 if self.release_dma_buffer(dmabuf).is_err() {
332 warn!("failed to release dma buffer");
333 }
334 }
335 }
336
337 Ok(())
338 }
339
340 pub fn reset(&self) -> Result<()> {
342 let vid = self.device_descriptor_tree.idVendor;
345 let pid = self.device_descriptor_tree.idProduct;
346 match (vid, pid) {
347 (0x1a6e, 0x089a) => (),
348 _ => return Ok(()),
349 }
350
351 let result = unsafe { self.ioctl(usb_sys::USBDEVFS_RESET) };
354
355 if let Err(Error::IoctlFailed(_nr, errno_err)) = result {
356 if errno_err.errno() == libc::ENODEV {
359 return Ok(());
360 }
361 }
362
363 result?;
364 Ok(())
365 }
366
367 pub fn claim_interface(&self, interface_number: u8) -> Result<()> {
369 let disconnect_claim = usb_sys::usbdevfs_disconnect_claim {
370 interface: interface_number.into(),
371 flags: 0,
372 driver: [0u8; 256],
373 };
374 unsafe {
378 self.ioctl_with_ref(usb_sys::USBDEVFS_DISCONNECT_CLAIM, &disconnect_claim)?;
379 }
380
381 Ok(())
382 }
383
384 pub fn release_interface(&self, interface_number: u8) -> Result<()> {
386 let ifnum: c_uint = interface_number.into();
387 unsafe {
391 self.ioctl_with_ref(usb_sys::USBDEVFS_RELEASEINTERFACE, &ifnum)?;
392 }
393
394 Ok(())
395 }
396
397 pub fn set_interface_alt_setting(
399 &self,
400 interface_number: u8,
401 alternative_setting: u8,
402 ) -> Result<()> {
403 let setinterface = usb_sys::usbdevfs_setinterface {
404 interface: interface_number.into(),
405 altsetting: alternative_setting.into(),
406 };
407 unsafe {
411 self.ioctl_with_ref(usb_sys::USBDEVFS_SETINTERFACE, &setinterface)?;
412 }
413 Ok(())
414 }
415
416 pub fn set_active_configuration(&mut self, config: u8) -> Result<()> {
418 let config: c_int = config.into();
419 unsafe {
423 self.ioctl_with_ref(usb_sys::USBDEVFS_SETCONFIGURATION, &config)?;
424 }
425
426 Ok(())
427 }
428
429 pub fn get_device_descriptor(&self) -> Result<DeviceDescriptor> {
431 Ok(*self.device_descriptor_tree)
432 }
433
434 pub fn get_device_descriptor_tree(&self) -> &DeviceDescriptorTree {
435 &self.device_descriptor_tree
436 }
437
438 pub fn get_config_descriptor(&self, config: u8) -> Result<ConfigDescriptorTree> {
440 match self.device_descriptor_tree.get_config_descriptor(config) {
441 Some(config_descriptor) => Ok(config_descriptor.clone()),
442 None => Err(Error::NoSuchDescriptor),
443 }
444 }
445
446 pub fn get_config_descriptor_by_index(&self, config_index: u8) -> Result<ConfigDescriptorTree> {
449 match self
450 .device_descriptor_tree
451 .get_config_descriptor_by_index(config_index)
452 {
453 Some(config_descriptor) => Ok(config_descriptor.clone()),
454 None => Err(Error::NoSuchDescriptor),
455 }
456 }
457
458 pub fn get_active_configuration(&self) -> Result<u8> {
460 if self.device_descriptor_tree.bNumConfigurations == 1 {
463 if let Some(config_descriptor) = self
464 .device_descriptor_tree
465 .get_config_descriptor_by_index(0)
466 {
467 return Ok(config_descriptor.bConfigurationValue);
468 }
469 }
470
471 let mut active_config: u8 = 0;
473 let ctrl_transfer = usb_sys::usbdevfs_ctrltransfer {
474 bRequestType: control_request_type(
475 ControlRequestType::Standard,
476 ControlRequestDataPhaseTransferDirection::DeviceToHost,
477 ControlRequestRecipient::Device,
478 ),
479 bRequest: StandardControlRequest::GetConfiguration as u8,
480 wValue: 0,
481 wIndex: 0,
482 wLength: size_of_val(&active_config) as u16,
483 timeout: 5000, data: &mut active_config as *mut u8 as *mut c_void,
485 };
486 unsafe {
490 self.ioctl_with_ref(usb_sys::USBDEVFS_CONTROL, &ctrl_transfer)?;
491 }
492 Ok(active_config)
493 }
494
495 pub fn get_num_configurations(&self) -> u8 {
497 self.device_descriptor_tree.bNumConfigurations
498 }
499
500 pub fn clear_halt(&self, ep_addr: u8) -> Result<()> {
502 let endpoint: c_uint = ep_addr.into();
503 unsafe {
507 self.ioctl_with_ref(usb_sys::USBDEVFS_CLEAR_HALT, &endpoint)?;
508 }
509
510 Ok(())
511 }
512
513 pub fn get_speed(&self) -> Result<Option<DeviceSpeed>> {
515 let speed = unsafe { self.ioctl(usb_sys::USBDEVFS_GET_SPEED) }?;
517 match speed {
518 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)), _ => {
525 error!("unexpected speed: {:?}", speed);
526 Ok(None)
527 }
528 }
529 }
530
531 pub fn alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()> {
533 let mut streams = vec_with_array_field::<usb_sys::usbdevfs_streams, c_uchar>(1);
534 streams[0].num_streams = num_streams as c_uint;
535 streams[0].num_eps = 1 as c_uint;
536 let eps = unsafe { streams[0].eps.as_mut_slice(1) };
539 eps[0] = ep as c_uchar;
540 unsafe {
544 self.ioctl_with_ref(usb_sys::USBDEVFS_ALLOC_STREAMS, &streams[0])?;
545 }
546 Ok(())
547 }
548
549 pub fn free_streams(&self, ep: u8) -> Result<()> {
551 let mut streams = vec_with_array_field::<usb_sys::usbdevfs_streams, c_uchar>(1);
552 streams[0].num_eps = 1 as c_uint;
553 let eps = unsafe { streams[0].eps.as_mut_slice(1) };
556 eps[0] = ep as c_uchar;
557 unsafe {
561 self.ioctl_with_ref(usb_sys::USBDEVFS_FREE_STREAMS, &streams[0])?;
562 }
563 Ok(())
564 }
565}
566
567impl AsRawDescriptor for Device {
568 fn as_raw_descriptor(&self) -> RawDescriptor {
569 self.fd.as_raw_descriptor()
570 }
571}
572
573impl Transfer {
574 fn urb(&self) -> &usb_sys::usbdevfs_urb {
575 &self.urb[0]
578 }
579
580 fn urb_mut(&mut self) -> &mut usb_sys::usbdevfs_urb {
581 &mut self.urb[0]
582 }
583
584 fn new(
585 transfer_type: u8,
586 endpoint: u8,
587 buffer: TransferBuffer,
588 iso_packets: &[usb_sys::usbdevfs_iso_packet_desc],
589 ) -> Result<Transfer> {
590 let mut transfer = Transfer {
591 urb: vec_with_array_field::<usb_sys::usbdevfs_urb, usb_sys::usbdevfs_iso_packet_desc>(
592 iso_packets.len(),
593 ),
594 buffer,
595 callback: None,
596 };
597
598 transfer.urb_mut().urb_type = transfer_type;
599 transfer.urb_mut().endpoint = endpoint;
600 transfer.urb_mut().buffer = transfer.buffer.address().ok_or(Error::InvalidBuffer)?;
601 transfer.urb_mut().buffer_length = transfer
602 .buffer
603 .size()
604 .ok_or(Error::InvalidBuffer)?
605 .try_into()
606 .map_err(Error::InvalidBufferLength)?;
607
608 let iso_frame_desc = unsafe {
612 transfer
613 .urb_mut()
614 .iso_frame_desc
615 .as_mut_slice(iso_packets.len())
616 };
617 iso_frame_desc.copy_from_slice(iso_packets);
618
619 Ok(transfer)
620 }
621
622 pub fn new_control(buffer: TransferBuffer) -> Result<Transfer> {
624 let endpoint = 0;
625 Self::new(usb_sys::USBDEVFS_URB_TYPE_CONTROL, endpoint, buffer, &[])
626 }
627
628 pub fn new_interrupt(endpoint: u8, buffer: TransferBuffer) -> Result<Transfer> {
630 Self::new(usb_sys::USBDEVFS_URB_TYPE_INTERRUPT, endpoint, buffer, &[])
631 }
632
633 pub fn new_bulk(
635 endpoint: u8,
636 buffer: TransferBuffer,
637 stream_id: Option<u16>,
638 ) -> Result<Transfer> {
639 let mut transfer = Self::new(usb_sys::USBDEVFS_URB_TYPE_BULK, endpoint, buffer, &[])?;
640 if let Some(stream_id) = stream_id {
641 transfer.urb_mut().number_of_packets_or_stream_id = stream_id as u32;
642 }
643 Ok(transfer)
644 }
645
646 pub fn new_isochronous(endpoint: u8, buffer: TransferBuffer) -> Result<Transfer> {
648 Self::new(usb_sys::USBDEVFS_URB_TYPE_ISO, endpoint, buffer, &[])
650 }
651
652 pub fn status(&self) -> TransferStatus {
654 let status = self.urb().status;
655 if status == 0 {
656 TransferStatus::Completed
657 } else if status == -ENODEV {
658 TransferStatus::NoDevice
659 } else if status == -ENOENT {
660 TransferStatus::Cancelled
661 } else if status == -EPIPE {
662 TransferStatus::Stalled
663 } else {
664 TransferStatus::Error
665 }
666 }
667
668 pub fn actual_length(&self) -> usize {
671 self.urb().actual_length as usize
672 }
673
674 pub fn set_callback<C: 'static + Fn(Transfer) + Send + Sync>(&mut self, cb: C) {
676 self.callback = Some(Box::new(cb));
677 }
678}
679
680impl TransferHandle {
681 pub fn cancel(&self) -> Result<()> {
685 let rc_transfer = match self.weak_transfer.upgrade() {
686 None => return Err(Error::TransferAlreadyCompleted),
687 Some(rc_transfer) => rc_transfer,
688 };
689
690 let urb_ptr = rc_transfer.urb.as_ptr() as *mut usb_sys::usbdevfs_urb;
691 let fd = match self.fd.upgrade() {
692 None => return Err(Error::NoDevice),
693 Some(fd) => fd,
694 };
695
696 if unsafe {
700 handle_eintr_errno!(base::ioctl_with_mut_ptr(
701 &*fd,
702 usb_sys::USBDEVFS_DISCARDURB,
703 urb_ptr
704 ))
705 } < 0
706 {
707 return Err(Error::IoctlFailed(
708 usb_sys::USBDEVFS_DISCARDURB,
709 base::Error::last(),
710 ));
711 }
712
713 Ok(())
714 }
715}